stdin
は、デフォルトでバッファリングされた入力であることがわかっています。その証拠は、scanf()
など、stdin
に「データを残す」メカニズムの使用にあります。
int main()
{
char c[10] = {'\0'};
scanf("%9s", c);
printf("%s, and left is: %d\n", c, getchar());
return 0;
}
./a.out
こんにちは
こんにちは、左は10です
10
もちろん改行です...
私はいつも興味がありますが、そこにあるものを削除せずにstdin
バッファを「覗く」方法はありますか?
[〜#〜]編集[〜#〜]
より良い例は次のとおりです。
scanf("%9[^.]", c);
「at.ct」を入力すると、「データ」(ct\n
)改行だけでなく、stdin
のままにしておきます。
移植性がありますが、getchar()
を使用して入力ストリーム内の次の文字を取得し、ungetc()
を使用してプッシュバックできます。これにより、文字がストリームから削除されていないかのような状態になります。 。
ungetc
関数は、c
で指定された文字(unsigned char
に変換)を、streamが指す入力ストリームにプッシュバックします。プッシュバックされた文字は、そのストリームでの後続の読み取りによって、プッシュの逆の順序で返されます。
標準ではプッシュバックの1文字のみが保証されていますが、通常はさらにプッシュバックできます。
他の回答で述べたように、それぞれ。そこにあるコメントは、実際には、独自のバッファーにsetvbuf
を指定すれば、ほぼ確実にバッファーを覗くことができますが、問題がないわけではありません。
buf
がnullポインターでない場合は、setvbuf
関数によって割り当てられたバッファーの代わりにそれが指す配列を使用できます。
そのため、提供されたバッファーがまったく使用されない可能性があります。
配列の内容はいつでも不確定です。
つまり、バッファの内容が実際の入力を反映しているという保証はありません(また、自動保存期間がある場合は、バッファの使用が未定義の動作になります)。
ただし、実際には、主な問題は、バッファ内のバッファ入力のまだ消費されていない部分がどこから始まり、どこで終わるかを見つけることです。
stdin
バッファーを変更せずに確認したい場合は、アクセス可能な配列を使用して、 setbuf
で別のバッファーを使用するように指示できます。
char buffer[BUFSIZ];
if (setbuf(stdin, buffer) != 0)
// error
getchar();
printf("%15s\n", buffer);
これにより、ungetc
以上のものを見ることができますが、ポータブルな方法でさらに先に進むことはできないと思います。
実際、これは合法ですが、標準には正しくありません。setvbuf
について引用します(setbuf
も同じ動作をします)。
配列の内容はいつでも不確定です。
したがって、完全な移植性と標準への準拠を求めている場合、これは必要なものではありませんが、バッファに期待されるものが含まれていてはならない理由は想像できません。しかし、それは私のコンピュータで動作するようです。
少なくともBUFSIZ
文字の配列をsetbuf
に提供する必要があり、その前にストリームでI/O操作を実行してはならないことに注意してください。さらに柔軟性が必要な場合は、 setvbuf
をご覧ください。
Stdinで setvbuf
を使用して独自のバッファを設定し、いつでもそこを覗くことができます。