タイトルはかなり自明です。
char c = std::cin.peek(); // sets c equal to character in stream
おそらくネイティブ型のcharはEOFを保持できないことに気づきました。
ありがとう、nmr
簡単な答え:いいえ。charの代わりにintを使用してください。
もう少し長い答え:いいえ。CのgetcharやC ++のpeekなどの関数から文字または値EOFを取得できる場合、すべての有効な文字と値EOFの両方を保持するには、明らかに通常のchar変数では不十分です。
さらに長い答え:状況によって異なりますが、期待どおりに機能することはありません。
CおよびC++には、 char、signed char、およびunsigned charの3つの文字タイプがあります(「ワイド」タイプを除く)。プレーン文字は符号付きまたは符号なしにすることができ、これはコンパイラによって異なります。
値EOFは負の整数であり、通常は-1であるため、 unsignedcharまたはunsignedのプレーンcharに格納することはできません。システムが8ビット文字(ほぼすべてが使用)を使用していると仮定すると、EOFは(10進数の)255に変換され、プログラムは機能しません。
ただし、char型が署名されている場合、またはsigned char型を使用している場合は、はい、-1を格納できるため、EOFを保持できます。しかし、ファイルからコード255の文字を読み取るとどうなりますか?これは-1、つまりEOFとして解釈されます(実装で-1を使用すると仮定)。したがって、コードはファイルの最後だけでなく、255文字が見つかるとすぐに読み取りを停止します。
の戻り値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_type
std::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') ...
が、正しい結果が得られない場合があります。一貫した結果を得るには、文字定数上または上で使用する必要があります。(ただし、通常、基本的な文字セットのメンバーで安全です。)ch
int
std::char_traits<char>::to_char_type
ch
std::char_traits<char>::to_int_type