1

タイトルはかなり自明です。

char c = std::cin.peek(); // sets c equal to character in stream

おそらくネイティブ型のcharはEOFを保持できないことに気づきました。

ありがとう、nmr

4

2 に答える 2

9

簡単な答え:いいえ。charの代わりにintを使用ください

もう少し長い答え:いいえ。CのgetcharやC ++のpeekなどの関数から文字または値EOFを取得できる場合、すべての有効な文字EOFの両方を保持するには、明らかに通常のchar変数では不十分です。

さらに長い答え:状況によって異なりますが、期待どおりに機能することはありません。

CおよびC++には、 charsigned char、およびunsigned charの3つの文字タイプがあります(「ワイド」タイプを除く)。プレーン文字は符号付きまたは符号なしにすることができ、これはコンパイラによって異なります。

EOFは負の整数であり、通常は-1であるため、 unsignedcharまたはunsignedのプレーンcharに格納することはできません。システムが8ビット文字(ほぼすべてが使用)を使用していると仮定すると、EOFは(10進数の)255に変換され、プログラムは機能しません。

ただし、char型が署名されている場合、またはsigned char型を使用している場合は、はい、-1を格納できるため、EOFを保持できます。しかし、ファイルからコード255の文字を読み取るとどうなりますか?これは-1、つまりEOFとして解釈されます(実装で-1を使用すると仮定)。したがって、コードはファイルの最後だけでなく、255文字が見つかるとすぐに読み取りを停止します。

于 2009-12-05T08:42:14.090 に答える
4

の戻り値std::cin.peek()は実際にはタイプstd::basic_ios<char>::int_typeであることに注意してください。これは、と同じでstd::char_traits<char>::int_typeあり、ではintありませんchar

それよりも重要なのは、そこに返される値はint必ずしもからcharへの単純なキャストではなく、ストリーム内の次の文字intを呼び出した結果であるか、文字がない場合は(と定義されています)です。std::char_traits<char>::to_int_typestd::char_traits<char>::eof()EOF

fgetc通常、これはすべて、戻り値として文字をにキャストしてからにキャストするのとまったく同じ方法で実装されるunsigned charためint、すべての有効な文字値をから区別できますEOF

の戻り値をに格納するstd::cin.peek()char、正の値を持つ文字(たとえば、iso-8859-1エンコードファイルのÿ)を読み取ると、と比較される可能性がありますEOF

やるべき衒学的なことはそうなるでしょう。

typedef std::istream::traits_type traits_type;

traits_type::int_type ch;
traits_type::char_type c;

while (!traits_type::eq_int_type((ch = std::cin.peek()), traits_type::eof()))
{
    c = traits_type::to_char_type(ch);
    // ...
}

これはおそらくもっと普通でしょう:

int ch;
char c;

while ((ch = std::cin.peek()) != EOF)
{
    c = std::iostream::traits_type::to_char_type(ch);
    // ...
}

文字値を正しく変換することが重要であることに注意してください。次のような比較を実行すると、上記のようになりますif (ch == '\xff') ...が、正しい結果が得られない場合があります。一貫した結果を得るには、文字定数上または上で使用する必要があります。(ただし、通常、基本的な文字セットのメンバーで安全です。)chintstd::char_traits<char>::to_char_typechstd::char_traits<char>::to_int_type

于 2009-12-05T11:35:51.063 に答える