2016-05-17 4 views
1

charでファイルcharを読み込み、EOFに達するまでコンソールに出力するはずの関数があります。この関数は、私が望むすべての文字を表示してもうまく動作しますが、それはそのまま続行し、最後には決して停止しません。関数の問題EOF

以下

は機能が

の下にリストされているファイルの

void displayAllLines(ifstream &joke) 
{ 
    char ch; 
    joke.clear(); 
    ch = joke.get(); 
    while (ch != EOF) 
    { 
     cout << ch; 
     ch = joke.get(); 
    } 
} 

内容である "(空白行) Q:?舌が歯に何と言いました"

私が述べたように、それは線がうまく表示されますが、ループは疑問符の後に続きます。

これはどういう考えですか?また、私の質問に適切に答えるために必要な情報が増えていますか?

答えて

1

これを行うための標準的な方法は次のとおりです。

void displayAllLines(ifstream &joke) 
{ 
    char ch; 
    while (true) 
    { 
     ch = joke.get(); 
     if (joke) { 
      cout << ch; 
     } else { 
      break; 
     } 
    } 
} 

それがEOFに到達するまで表現jokeが真と評価されます。どうして最初にjoke.clear()に電話したいと思うのか分かりません。

+1

ファイルで始めるときに教えたのは単なる習慣です。最初にそれにフラグがないことを確認するだけです。あなたはそれが無意味だと思いますか、それともおそらくプログラムに有害だと思いますか? EDIT ::あなたが投稿したコードは確かにプログラムをさらに進めますが、スペース文字は考慮されず、空白のないすべてが表示されます – Podo

+0

また、私のコードが*作業。 – Podo

+0

私はあなたが盲目的に '' clear() ''を呼ぶべきではないと思います。フラグが設定されている場合は、理由があり、クリアするだけでは役に立ちません。あなたのコードは、C++のストリームはCのようにEOFを文字として読み込まないので動作しません。 C++ストリームは、EOFに達するまで文字を読み取ります。 (実際にはEOF文字を返すことはありません - それはCです。) – Phil

1

@Philは「C++でこれを行う方法」と答えました。私の答えは「なぜこれが起きているのか」と「Cでこれを行う方法」(それはC++でも動作します)に入ります。 ASCIIテーブルは最大1からのすべての道を行くと、私たちは、文字列の終了(話CおよびC++言語)のために予約バイト値0('\0'を持っているので


は、EOFは外の特別な値であることが必要ですそれの。

だからこそgetchar()ifstream::get()はであり、charではありません。だから、すべてを行う必要がある

int ch; 

char ch; 

を変更して、印刷のためにchar型にキャストされています。技術的には、EOFは通常-1ある

cout << (char) ch; 

charの範囲は0 - 255であり、決して-1と等しくなることはありません。 -Wallが有効になっているまともなコンパイラは、少なくとも警告を出すはずです。

+0

より一般的に、' int'の代わりに 'std :: istream :: traits_type :: int_type'を使用してください。これはASCIIだけでなくすべての文字エンコーディングで機能します。 –