2

次のコードに関して混乱しています。

#include<stdio.h>

int main()
{
 char buf[100]={'\0'};
 int data=0;
 scanf("%d",&data);
 read(stdin,buf,4);         //attaching to stdin
 printf("buffer is %s\n",buf);

 return 1;
 }

実行時に入力を提供したとします10abcd。私の理解によれば、次のことが起こるはずです。

  1. scanf は10データに配置する必要があります
  2. abcdまだ標準入力バッファにあります
  3. read が stdin を読み込もうとするとき (既にabcdそこにあります) abcd、 をbuf
  4. したがって、printfは印刷する必要がありますabcd

しかし、それは起こっていません.printfはo / pを示していません

ここで何か不足していますか?

4

3 に答える 3

4

まず第一に、注意するのread (stdin, ...)が賢明な警告を表示する必要があります (有効にしている場合)。 read()どのチャネルから読み取るかを指定する最初のパラメータとして整数を取ります。 stdinタイプFILE *です。

に変更したとしてもread(0,...、これは推奨される方法ではありません。 ファイル ハンドル 0 からバッファリングされている scanf読み取り元です。基になるファイル ハンドルから直接読み取り、バッファリングされた文字を無視します。がバッファなしに設定されていない限り、これは奇妙な結果を引き起こします。FILE *stdinread (0, ...)stdin

于 2013-04-01T06:09:56.693 に答える
3

read()関数呼び出しの構文に関連する機械的な問題を無視すると、次の 2 つのケースを考慮する必要があります。

  1. 入力は端末からです。
  2. 入力はファイルからです。

「ターミナル」

ユーザーがリターンを押すまで、データを読み取ることはできません。その時点で、標準 I/O ライブラリは、利用可能なすべてのデータを関連するバッファstdin("10abcd\n") に読み込みます。a次に、数値を解析し、後で他の標準 I/O 関数によって読み取られるようにバッファに残します。

これがread()発生すると、ユーザーが何らかの入力を提供するのも待機します。バッファ内のデータについての手がかりはありませんstdin。ユーザーが return を押すまでハングし、次の大量のデータを読み取り、バッファーに最大 4 バイトを返します (4 番目の文字が ASCII NUL でない限り、null 終了はありません'\0')。

ファイル

実際には、これはそれほど大きな違いはありませんが、標準 I/O ライブラリは、1 行のデータをバッファーに読み込む代わりに、おそらくバッファー全体 ( BUFSIZ512 バイト以上になる可能性があります) を読み込むことになります。次に、 を変換し、後で使用するために10を残します。a(ファイルがバッファ サイズより短い場合は、すべてバッファに読み込まれますstdin。)

read、ファイルから次の 4 バイトを収集します。ファイル全体が既に読み取られている場合は、何も返されません — 0 バイトが読み取られました。


からの戻り値を記録して確認する必要がありますread()。からの戻り値もチェックして、scanf()実際に数値を読み取ったことを確認する必要があります。

于 2013-04-01T06:23:03.990 に答える
1

試してみてください...man read最初に。

read は ssize_t read(int fd, void *buf, size_t count); として宣言されます。

stdin は FILE * として宣言されます。それが問題です。代わりに fread() を使用すると、ソートされます。

int main()
{
 char buf[100]={'\0'};
 int data=0;
 scanf("%d",&data);

 fread(buf, 1, 4, stdin);
 printf("buffer is %s\n",buf);

 return 1;
}

編集:あなたの理解はほぼ正しいですが、完全ではありません。あなたの質問に適切に答えるために、私はジョナサン・ラッファーに同意します.

あなたのコードがどのように機能するか、

1) scanf は data に 10 を配置する必要があります。

2) ENTER を押すと、abcd は stdin バッファーに残ります。

3) その後、 read() は再び入力を待ちます。プログラムをさらに実行するには、もう一度 ENTER を押す必要があります。

4)Enterを2回押す前に何かを入力した場合、printfはそれを印刷する必要があります。それ以外の場合、printfステートメント以外の出力は得られません。

そのため、代わりに fread を使用するように依頼しました。それが役に立てば幸い。

于 2013-04-01T06:14:51.680 に答える