1. ホーム
  2. C++

EOFの意味と使い方 (while(scanf("%d",&n) !)) = EOF))

2022-02-26 06:55:20
<パス

EOFはEnd Of Fileの略で、通常、データの終わりを示すためにテキストの末尾に存在します。
この時点で、アプリケーションはデータソースがターミナル(または他の文字デバイス)であることを認識し、既知の予約文字またはシーケンスをファイルの終わりを示すものとして解釈します。最も一般的なのは、ASCII文字の置換(Control-Z、コード26)です。
C言語では EOF(End of File)は、正確にはC標準ライブラリで表現されます。whileループの中のファイル終了マーカーはEOFです。EOFをファイル終了マーカーとするファイルは、テキストファイルでなければならない。テキストファイルでは、データは文字のASCIIコード値という形で保存されている。ASCIIコード値の範囲は0〜127であり、-1はありえないことが分かっているので、EOFをファイル終了フラグとして使用することができる。
ファイルアクセスやその他のI/O関数は、ファイルの終わりを示すために、シンボル値(マクロ)EOFと等しい値を渡すことがある。実際には、EOF の値は通常 -1 であるが、システムによって異なる。マクロ EOF は、生コードをコンパイルする前に、プリプロセッサに実際の値を展開します。
C言語では、EOFはしばしばファイル終了フラグとして使用されます。また、ファイル処理関数には、エラーの後にEOFの値を返すものが多いので、関数呼び出しが成功したかどうかを判断するのに使われることも多い。
例えば

#include <stdio.h>
int main(){
	int n;
while(scanf("%d",&n) ! = EOF){ 
	
}
	return 0;
}


上記のプログラムを実行するとき、" を付けなければ、 ! = EOF"を付けないとデッドループになってしまい、そのまま実行され続けますが、" ! = EOF" を付けると、デッドループにはならず、端末からの入力がなければ自動的に終了します(whileは、現在の入力キャッシュに何かある間は読み続け、入力キャッシュが空になったら止めるという意味です)。
この中で "scanf("%d",&n) ! = EOF" は、 "scanf("%d",&n) ! = EOF" または "~scanf("%d",&n)" または "scanf("%d",&n) == 1 " 。scanf の戻り値は、後続の引数によって決定されます。

上記のプログラムはどのように終了するのかという疑問をお持ちの方もいらっしゃると思います。
<マーク ターミナル(ブラックボックス)で手動で入力する場合、システムはいわゆる "end of file" に到達したことを知らないので、 <Ctrl + z> キーの組み合わせを使用して Enter を押して EOF に到達したことをシステムに伝え、その間システムが終了するようにする必要があることに注意してください。

scanf("%d%d", &a, &b);
aとbの両方が正常に読み込まれた場合、scanfの戻り値は2、aだけが正常に読み込まれた場合、戻り値は1、aとbの両方が正常に読み込まれなかった場合、戻り値は0、エラーが発生したかファイルの終わりに遭遇した場合、戻り値はEOF、戻り値はintとなる。

ただし、この使い方はC++には存在せず、同じ効果でwhile((cin >> a) ! = 0).
whileの中でcin >> a;を使う意味がわからなかった。cinはC++の入力ストリームオブジェクト、">"はオーバーロードした演算子、cin >> の戻り値はcinオブジェクト。これを条件とした場合はそのストリーム状態を検出して終了します。
(1) ストリームが有効である場合、すなわち、ストリームがエラーに遭遇していない場合、検出は成功する。
(2) ファイル終端文字に遭遇したり、不正な入力(例えば、この質問で入力された値は整数ではない)に遭遇すると、istreamオブジェクトの状態はinvalidに変化し、条件はfalseとなります。読み込みに失敗すると、読み込みを継続できなくなるので、読み込み操作は終了し、while(cin>>a)はfalseを返してループはジャンプアウトされるのです
C++ while (cin>>n,n).
この人がやっていることは、「数値を入力し、この数値が0でないときにループに入り、0になったときにループから飛び出す」ということです。

採用されたのは、"https://www.cnblogs.com/tgycoder/p/4958519.html"。

入力(cin)バッファはラインバッファである。キーボードから文字列が入力され、キャリッジリターンが押されると、それらの文字はまず入力バッファに送られ、保存されます。Enter キーが押されるたびに、cin は入力バッファに読み取り可能なデータがあるかどうかを確認します。この場合、cin はキーボードのストリーム終了フラグ CTRL+Z または CTRL+D を、ブロッキングとノンブロッキングの 2 つの方法のいずれかでチェックします。

ブロッキングチェックとは、Enterキーが押された後にCtrl+Zのキーの組み合わせが押された場合のみチェックし、ノンブロッキングチェックとは、Ctrl+Dが押された直後に反応することを意味します。Ctrl+Dを押す前にキーボードから文字が入力されていた場合、Ctrl+Dはキャリッジリターンとして動作し、入力バッファに文字を送り読み込み、Ctrl+Dはストリームターミネータとして動作しなくなる。Ctrl+Dを押す前にキーボードから何も入力されていない場合、Ctrl+Dはストリームの終了を示す信号となります。
このブロック方式には、Enterキーを押した後、その前にCtrl+Zが押されたかどうかだけを検出できる、という特徴があります。

参考 バイドゥ百科事典