13

私は C++ を学んでいて理解しようとして
います。行末に置かれた場合、EOF 文字 (Windows では Ctrl + Z) が while ループを壊さないのはなぜですか?

私のコード:

    int main() {
        char ch;
        while(cin >> ch) {
            cout << ch;
        }
    }

^Z と入力すると、ループが中断されます。
しかし、12^Z を入力すると、そうではありません。

4

3 に答える 3

9

あなたの質問に対する答えは、C++ 標準では見つかりません。

cin >> chファイルの終わり条件も入力エラーもない限り、「真」の条件になります。ファイルの終わりの条件がどのようにトリガーされるかは言語によって指定されておらず、オペレーティング システムごとに異なる可能性があり、同じ OS の構成オプションによっても異なる可能性があります。(たとえば、Unix ライクなシステムはデフォルトで control-D を使用しますが、これはsttyコマンドで変更できます。)

Windows は Control-Z を使用して、テキスト入力ストリームのファイル終了条件をトリガーします。たまたま行頭以外でそうしないだけです。

Unix の動作は少し異なります。行の先頭で Control-D (デフォルト) を使用するか、行の途中で2 つの Control-D を使用します。

Unix の場合、これは端末から読み取る場合にのみ適用されます。ファイルから読み込んでいる場合、control-D は別の非表示文字であり、ファイル終了条件をトリガーしません。Windows は、ディスク ファイルから読み取る場合でも、control-Z をファイルの終わりのトリガーとして認識するようです。

結論: オペレーティング システムが異なれば動作も異なりますが、その主な理由は、あいまいな歴史的な理由によるものです。C++ は、これらの動作のいずれでも動作するように設計されているため、一部の詳細については特定されていません。

于 2012-07-07T22:25:00.893 に答える
4

C および C++ 標準では、テキスト ストリームがテキスト モード(デフォルト) で非常に不道徳なことを行うことを許可しています。これらの Unholy Things には、内部の改行マーカーと外部の改行制御文字との間の変換、および特定の文字または文字シーケンスをファイルの終わりを示すものとして扱うことが含まれます。Unix ランドでは行われていませんが、Windows ランドでは行われているため、コードは元の Unix ランドの規則にのみ関連付けることができます。

これは、Windows では、入力を正確に入力にコピーする移植可能な C または C++ プログラムを作成する方法がないことを意味します。

Unix ランドにいる間は、まったく問題ありません。

Windows では、単一の [Ctrl Z] で構成される行は、慣例によりファイルの終わりマーカーです。これは、コンソールだけでなく、テキスト ファイルでも同様です (ツールによって多少異なります)。Windows はこれを DOS から継承し、DOS は CP/M から一般的な考え方を継承しました。

CP/M がどこから入手したかはわかりませんが、Unix の [Ctrl D] とまったく同じではなく、似ているだけです。

Unix ランドでは、ファイルの終わりの一般的な慣例は、単に「これ以上データがない」ことです。コンソールで [Ctrl D] を押すと、デフォルトで入力したテキストが待機中のプログラムにすぐに送信されます。行にまだ何も入力していない場合、0 バイトが送信され、0 バイトを返す読み取りは慣例によりファイルの終わりに遭遇します。

主な違いは、Windows では内部的にファイル内で発生する可能性があるファイル マーカーのテキスト終了はdataであるのに対し、Unix では内部的にはファイル内で発生する可能性がないdata の欠如です。もちろん、Windows はテキストの通常のファイルの終わり (これ以上のデータはありません!) もサポートしています。これは物事を複雑にします – Windows はもっと複雑です。


#include <iostream>
using namespace std;

int main()
{
    char ch;
    while(cin >> ch) {
        cout << 0+ch << " '" << ch << "'" << endl;
    }
}
于 2012-07-07T22:25:53.453 に答える
1

これは cin >> ^Z が false に評価されることが原因です。

詳細: cin.eof() は true を返すため、暗黙的に eof() を呼び出す while は false を返し、ループを終了します。

12^Z を入力すると、有効な入力値を解析できるため、eof() は false を返し、ループを停止しません。

このSOにも興味があるかもしれません:

フラグのセマンティクスに関する SO

于 2012-07-07T21:59:35.303 に答える