1

ここで達成しようとしているのは、cString を取得し、特定の文字を strchr() 関数を使用して見つけた別の場所に置き換えることです。

私が理解できないのは、私のすべての試み(以下にコメントアウト)で文字を置き換える方法はすべて、編集されていない文字列を生成するか、プログラムをクラッシュさせる方法です。文字を置き換えることで正しい方向に進んでいると思います(char * cの開始アドレスを取得し、n(置き換えたい文字の前方のバイト数)を追加してから、その新しいアドレスに書き込みます)。私はそれを正しく機能させることができないようです。

どんな助けでも大歓迎です。

int main()
{
    char *c, *sch;
    int n;

    c = "this is a test\n";

    sch = strchr(c, 'a');

    if(sch != NULL)
    {
        n = sch-c+1;

        printf("%d\n", (int)sch);
        printf("%d\n\n", (int)c);

        printf("'a' found at: %d", n);
    }

    /////////////////////
    //sch = &c;
    //*(sch + n) = 'z';
    /////////////////////
    //*(c + n) = 'z';
    /////////////////////
    //c[n] = 'z';
    /////////////////////

    printf("\n\n%s", c);

    getchar();
    return 0;
}
4

5 に答える 5

2

編集: まず第一にc、文字列リテラルは読み取り専用メモリに格納されているため、文字列リテラルへのポインターではなく配列である必要があり、それらを変更しようとすると通常クラッシュします。

ですから、まず第一に、

char c[]= "this is a test\n"

これにより、変更可能な文字列がその値に初期化され、問題なく編集できます。

一般に、文字列リテラルを に直接割り当てるべきではありませんchar *。この種の問題が発生する可能性があるためです。代わりに、それらを にのみ割り当ててください。そうすればconst char *、変更を試みるとコンパイル エラーが発生します。


次に、strchrすでに一致する文字へのポインターを返します (ドキュメントに記載されているように)。直接変更するだけで、ポインター演算は含まれません。

*sch = 'z';

それでも、ポインター演算を試してみたい場合は、 の定義にエラーがありますn

n = sch-c+1;

それを文字列のインデックスとして使用する場合は、配列 (および文字列) がゼロベースであるため、その 1 を削除する必要があります。つまり、その値に割り当てる場合n、次のコード:

*(c + n) = 'z';

(これは

c[n] = 'z';

)

意味します

*(c + sch - c + 1) 

あれは、

*(sch+1)

つまり、 で見つかった文字の次の文字strchr。を削除する+1と、そのトリックが実行されます (ただし、単に と言うのは複雑な方法です*sch='z')。

他の試みは間違っています。あなたのコードで&cchar **、つまり char へのポインタへのポインタであり、これはあなたが望むものではないからです。

于 2011-06-15T21:56:42.793 に答える
1

C では、引用符で囲まれた文字列は ですchar *が、それは変更できるという意味ではありません。c配列(char c [] = "this is a test\n";)として使用するか、メモリを割り当ててテキストをコピーしてみてください。

于 2011-06-15T21:58:57.393 に答える
1

コードではc、定数文字列 (文字列リテラル) を指します。それを変更すると、未定義の動作になります。代わりに char の配列にコピーする必要があります (例:

char c[] = "This is a test"

コメントアウトされた最初の試みは、のアドレスを取り、それを-cに入れます。これは、あなたが望むものではありません。ところで、コンパイラはそれを拾ったはずです-おそらく、さらにいくつかの警告をオンにします。schchar**

2 回目は問題なく、3 回目も基本的には同じです。

ところで: n は必要ありませんsch - c- は必要ありません。探している文字が見つからない場合に備えて、何かに+ 1初期化する必要があります..n

于 2011-06-15T22:00:52.933 に答える
0

ここでの問題は、ポインター演算ではありません (必要以上に複雑にしていますが、Matteo Italia の回答を参照してください)。

あなたの問題は、次のコードがあなたが思っていることをしないことです:

char *c;

c = "this is a test\n";

このコードはポインタを作成し、それに静的文字列のアドレスを割り当てます。Matteo の提案があっても、静的文字列を変更することはできません。

これを修正するには、次の 2 つの方法のいずれかを実行できます。配列として宣言cし、文字列で初期化できます。cをポインタのままにし、 を使用mallocしてバッファを割り当て (バッファのアドレスを に格納c)、 を使用strcpyして静的文字列をバッファにコピーすることもできます。その時点で、しようとしているように文字列を操作できるはずです。

于 2011-06-15T22:02:51.473 に答える
0
 #include <stdio.h>
 #include <string.h>

int main()
{
char c[80], *sch;
int n;


scanf("%s", c);printf("string %s \n", c);
//c = "this is a test\n";

sch = strchr(c, 'a');

if(sch != NULL)
{
    n = sch-c;

    printf("%d\n", (int)sch);
    printf("%d\n\n", (int)c);

    printf("'a' found at: %d", n);
}

/////////////////////
sch = &c;
*(sch + n) = 'z';
/////////////////////
*(c + n) = 'z';
/////////////////////
c[n] = 'z';
/////////////////////

printf("\n\n%s", c);

getchar();
return 0;

上記のスニペットを「this-is-a-test」という文字列で実行します

以前のコードの問題は、文字列リテラルが読み取り専用セクションになり、変更できないことです。したがって、char c[] ="this is a string" と書いても役に立ちません。

于 2011-06-15T22:15:18.557 に答える