0

文字列を別の文字列にコピーするコードを作成しましたが、各文字の間にスペースがあります。コードを実行すると、文字列の後に「ガベージ」が表示されます。ただし、最後のforループがコメント化されていない場合、後にガベージはありません。なぜこれが起こっているのか誰もが知っていますか?

#include<stdio.h>
#include<string.h>

#define MAX_SIZE 20
main ()
{
    char name[MAX_SIZE+ 1]; 
    char cpy[(MAX_SIZE * 2) + 1];

    gets(name);

    int i = 0;

    while (name[i] != '\0' && i < MAX_SIZE)
    {
        cpy[(i * 2)] = name[i];
        cpy[(i * 2) + 1] = ' ';
        i++;
    }

    cpy[strlen(cpy)] = '\0';    

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

    //for (i = 0; i < strlen(cpy); ++i) {
    //    printf("%c", cpy[i]);
    //}

}
4

4 に答える 4

5

この線

cpy[strlen(cpy)] = '\0';

cpyはnullで終了していないため、機能しません。クラッシュするか、メモリの0バイトが見つかるまでstrlen、の終わりを超えて読み取ります。nameその行をに変更することでこれを修正できます

cpy[i*2] = '\0';

関数の最後でforループのコメントを外すと問題が解決するように見える場合は、呼び出しのi前に0にリセットされると推測できます。つまり、の直後にスタック上でnullターミネータが見つかります。これが起こっているのであれば、その非常に未定義の動作なので、信頼することはできません。printfprintfcpy

于 2013-03-05T13:25:20.790 に答える
2
 while (name[i] != '\0' && i < MAX_SIZE)
    {
        cpy[(i * 2)] = name[i];
        cpy[(i * 2) + 1] = ' ';
        i++;
    }
 cpy[(i * 2)] = 0x0;

文字列をnullで終了する必要があります。

于 2013-03-05T13:26:09.987 に答える
1

文字列を操作していることがわかっているので、「cpy」配列をヌル文字で初期化するとよいでしょう。

 char cpy[(MAX_SIZE * 2) + 1]  = "\0";

そうでなければ、私はsimoncの答えに同意しました。

于 2013-03-05T13:35:32.803 に答える
1

完全を期すために:

char* pcpy = cpy;
for (char const* p = fgets(name,sizeof(name)/sizeof(*name),stdin); p && *p; ++p) {
  *pcpy++ = *p;
  *pcpy++ = ' ';
}
*pcpy = 0;

データのオーバーランによってスタックが破損するのを防ぐためfgetsではなく、を使用する必要があります。次に、配列にgets格納されている文字列を手動で終了する必要があります。これは、最初のゼロまで文字数をカウントするだけだからです。したがって、まだ終了していない場合、の結果は未定義になり、プログラムがクラッシュする可能性があります。cpystrlencpystrlen(cpy)

于 2013-03-05T13:37:08.973 に答える