1

文字列の配列を定義しました。最初の要素が空の文字列ではないような方法で定義すると、うまく機能します。空の文字列の場合scanf()、他の文字列の次は入力文字列の読み取りを停止し、プログラムは実行を停止します。

文字列の配列を定義すると、 による入力の読み取りにどのように影響するかわかりませんscanf()

  char *str_arr[] = {"","abc","","","b","c","","",""}; // if first element is "abc" instead of "" then works fine

  int size = sizeof(str_arr)/sizeof(str_arr[0]);

  int i;

  printf("give string to be found %d\n",size);


  char *str;
  scanf("%s",str);
  printf("OK\n");
4

3 に答える 3

1

ポインタを宣言してもメモリ内にバッファが割り当てられず、初期化されないため、初期化されていないポインタ ( str) を逆参照しようとすると、未定義の動作が発生します。

scanf文字列を読み取るときに注意して使用しないと、バッファ オーバーフローが発生する可能性があることに注意してください。このページを読んで、それを回避する方法についてのアイデアを見つけることをお勧めします。

于 2013-07-01T19:12:05.593 に答える
1

実際、あなたは私の兄弟を誤解しています。の初期化は のstr_arr動作には影響しませんがscanf()、あなたにはそう思われるかもしれませんが、実際にはそうではありません。他の回答でも説明されているように、これは未定義の動作と呼ばれます。C 自体の未定義の動作は、非常に漠然と定義されています。

C FAQ では、「未定義の動作」を次のように定義しています。

何でも起こりえます。規格は要件を課していません。プログラムがコンパイルに失敗したり、正しく実行されなかったり (クラッシュしたり、暗黙のうちに間違った結果が生成されたり)、プログラマーが意図した通りに偶然に実行されたりする可能性があります。

それは基本的に何でも起こり得ることを意味します。このようにすると:

char *str;
  scanf("%s",str);

UBです。想定外の結果が得られ、それが機能していると思われる場合があります。デバッガーが役立つのは、ほとんどの場合、特に最初にデバッガーを使用する場合です。あなたのプログラムに関するその他の推奨事項:

  • 文字列の読み取りにscanf()使用する代わりに。fgets()scanf を使用する場合はscanf("%ws",name);、名前が文字配列でw、フィールド幅が次のように使用します。
  • -Wallオプションを使用してコンパイルすると、すべての警告が表示されますwarning that you are using str uninitialized

この記事を読み進めてください。疑問を解消するのに十分な情報が含まれています。

于 2013-07-03T07:04:35.580 に答える
0

scanf特定のものに初期化されていないポインターに渡しているためscanf、ユーザーが提供した文字をランダムなメモリ位置に書き込もうとします。これがクラッシュするか、それとも何か他の結果になるかは、ほとんどが運によるものです (また、コンパイラがどのようにスタックを設定するかを決定することも、「運」と見なされる可能性があります)。技術的には、これは「未定義の動作」と呼ばれます。つまり、C 標準に関する限り、何でも起こり得るということです。

scanf問題を解決するには、受け取る予定の文字列に十分な大きさのバッファに渡す必要があります。

char str[101];
scanf("%100s",str); /* the "100" bit tells to scanf to avoid reading more than 100  chars, which would result in a buffer overflow */
printf("OK\n");

char *そして、Cの は他の言語の と同等ではないことを覚えておいてください -は単なる へのポインタであり、割り当てについては何も知りません。stringchar *char

于 2013-07-01T19:15:01.987 に答える