1

このばかげた質問で申し訳ありません。ユーザーに年齢と名前を入力してから、年齢と名前を画面に出力するように求めるCプログラムがあります。これは本から読んだ私のエクササイズです。

これはプログラムです:

#include <stdio.h>

int main (void) {
   int age;
   char name[20];

   puts("Enter your age:");
   scanf("%d",&age);

   fflush(stdin);

   puts("Enter your name:");
   scanf("%s",name);

   printf("Your age is %d\n",age);
   printf("Your name is %s\n",name);

   return 0;
}

最初に余分な文字を入力するscanf()と、プログラムが終了し、余分な文字が次の文字に割り当てられますscanf()

次に、コードを変更し、名前付きの関数を追加し、その関数内でclear_buff()使用して、ストリームの残りの文字を読み取ります。コードは期待どおりに機能します。fgetsclear_buff()

#include <stdio.h>

#define MAXLEN 80

void clear_buff(void);

int main (void) {
  int age;
  char name[20];

  puts("Enter your age:");
  scanf("%d",&age);

  clear_buff();

  puts("Enter your name:");
  scanf("%s",name);

  printf("Your age is %d\n",age);
  printf("Your name is %s\n",name);

  return 0;
}

void clear_buff(void){
   char junk[20];
   fgets(junk,MAXLEN,stdin);
}

私の質問は、なぜfflush(stdin)このプログラムで働かないのですか?

この本には、fflush関数がストリーム上のバッファリングされたデータをクリアすると書かれています.I fflush()/ Oストリームを操作する場合、関数はC標準関数であることを知っています。

4

1 に答える 1

7

fflush出力ストリームまたは更新ストリームで動作することを意図しており、入力ストリームでそれを使用することは未定義の動作です。 fflushの cppreference C セクションから:

指定されたストリームが入力タイプである場合、または指定されたストリームが更新タイプであるが、最後の I/O 操作が出力操作ではなかった場合、動作は未定義です。

未定義の動作とは、標準で指定されていない動作であり、プログラムの結果が予測不可能であることを意味します。これは、正常に見える動作、クラッシュ、またはその他の望ましくない影響を意味する可能性があることを意味します。

7.19.5.2 cppreference は、ドラフト C99 標準セクションの言語と一致しています。

stream が、最新の操作が入力されていない出力ストリームまたは更新ストリームを指している場合、fflush 関数により、そのストリームの未書き込みデータがホスト環境に配信され、ファイルに書き込まれます。それ以外の場合、動作は未定義です。

これは実際にはあなたの質問ではなく、回避策を見つけたようですが、質問C, flushing stdin にはいくつかの適切な方法が記載されていますstdin

于 2014-10-19T01:26:40.860 に答える