#include <stdio.h>
int main() {
char read = ' ';
while ((read = getchar()) != '\n') {
putchar(read);
}
return 0;
}
私の入力はf
(もちろんエンターが続きます)です。getchar()
もう一度入力を求めると思いますが、代わりにプログラムが終了します。どうして?どうすればこれを修正できますか?
ターミナルは時々少し混乱することがあります。プログラムを次のように変更する必要があります。
#include <stdio.h>
int main() {
int read;
while ((read = getchar()) != EOF) {
putchar(read);
}
return 0;
}
これは、getchar が端末から EOF (ほとんどの場合、このマクロは -1 に展開されます) を読み取るまで読み取ります。getchar は int を返すので、変数を整数に「読み取る」ようにして、EOF をチェックできるようにする必要があります。Linux では ^D を使用して端末から EOF を送信できます。Windows では ^Z (?) を使用すると思います。
何が起こるかを少し説明します。あなたのプログラムでは式
(read = getchar()) !='\n'
'\n' がバッファから読み取られない限り、真になります。問題は、プログラムにバッファを取得するために、'\n' に対応するエンターを押さなければならないことです。プログラムが端末で呼び出されると、次の手順が実行されます。
~$\a.out
これはあなたのプログラムを開始します
(empty line)
getchar() は端末から入力を取得するためのシステム コールを作成し、端末が引き継ぎます
f
ターミナルで入力を行いました。「f」はバッファに書き込まれ、端末にエコーバックされます。プログラムはまだ文字について認識していません。
f
f~$
Enter キーを押します。バッファには「f\n」が含まれています。'enter' はまた、プログラムに戻る必要があることを端末に通知します。プログラムはバッファを読み取り、f を見つけて画面に表示し、'\n' を見つけてすぐにループを停止し、プログラムを終了します。
これは、ほとんどの端末の標準的な動作です。この動作は変更できますが、OS によって異なります。
getchar() は、入力ストリームから次の文字を返します。これにはもちろん改行なども含まれます。「Enter」を押さない限りループの進行状況が表示されないという事実は、ファイル I/O (stdin での作業) が入力バッファーを引き渡さないという事実によって引き起こされます。バッファの最後に '\n' が検出されない限り、getchar() へ。ルーチンは最初にブロックし、2 つのキーストロークを 1 回のラッシュで処理し、指定したように、入力ストリームに '\n' を表示して終了します。事実: getchar() は入力ストリームから '\n' を削除しません (なぜ削除する必要があるのでしょうか?)。
f の後に「/n」である「enter」を入れています。ループはそこで終了します。別の文字を取りたい場合は、Enter キーが押されるとすぐにループを終了します。
\n (入力) を読み取ったときにループが終了し、0 を返すようにプログラムしました。プログラムを終了する main から。
おそらくあなたは次のようなものが欲しい
while ((read = getchar()) != EOF) {
putchar(read);
}
n x 端末では、Control-D を押すと、tty ドライバーに入力バッファーを読み取り中のアプリに返すように指示できます。そのため、新しい行の ^D は入力を終了します。これにより、tty がゼロ バイトを返し、アプリがファイルの終わりとして解釈します。しかし、それは行のどこでも機能します。