标题非常不言自明。
char c = std::cin.peek(); // sets c equal to character in stream
我刚刚意识到也许本机类型 char 不能容纳 EOF。
谢谢,核磁共振
简短的回答:不。使用int而不是char。
稍微长一点的答案:不。如果您可以从函数中获取字符或值EOF,例如 C 的getchar和 C++ 的peek,显然普通的char变量不足以同时保存所有有效字符和值EOF。
更长的答案:这取决于,但它永远不会像你希望的那样工作。
C 和 C++ 具有三种字符类型(“宽”类型除外):char、signed char和unsigned char。普通字符可以是有符号或无符号的,这在编译器之间会有所不同。
值EOF是一个负整数,通常为 -1,因此很明显,您不能将它存储在无符号字符或无符号普通字符中。假设您的系统使用 8 位字符(几乎所有字符都使用),EOF将转换为(十进制)255,您的程序将无法运行。
但是,如果您的char类型是有符号的,或者如果您使用有符号的 char类型,那么是的,您可以在其中存储 -1 ,所以是的,它可以保存EOF。但是,当您从文件中读取代码为 255 的字符时会发生什么?它将被解释为-1,即EOF(假设您的实现使用-1)。因此,您的代码不仅会在文件末尾停止读取,而且在找到 255 个字符时也会停止读取。
请注意,的返回值std::cin.peek()
实际上是类型std::basic_ios<char>::int_type
,与 相同std::char_traits<char>::int_type
,它是 anint
而不是 a char
。
更重要的是,返回的值int
不一定是从char
to的简单转换,int
而是调用std::char_traits<char>::to_int_type
流中的下一个字符或std::char_traits<char>::eof()
(定义为EOF
)如果没有字符的结果。
fgetc
通常,这一切的实现方式与将字符转换为 anunsigned char
然后转换为 an作为其返回值完全相同,int
这样您就可以区分所有有效的字符值和EOF
.
如果将 的返回值存储std::cin.peek()
在 achar
中,那么读取具有正值的字符(例如 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') ...
where ch
is anint
如上所述,您可能不会得到正确的结果。您需要使用std::char_traits<char>::to_char_type
onch
或std::char_traits<char>::to_int_type
on 字符常量来获得一致的结果。(不过,对于基本字符集的成员,您通常是安全的。)