标题非常自我解释。
char c = std::cin.peek(); // sets c equal to character in stream
我刚才意识到也许原生类型的char不能保持EOF。
感谢, NMR
答案 0 :(得分:8)
简短回答:否。使用 int 代替 char 。
稍微长一点的答案:不会。如果你可以从一个函数中获得一个字符或值 EOF ,例如C的 getchar 和C ++的 peek ,显然正常的 char 变量不足以同时保存所有有效字符和值 EOF 。
更长的答案:这取决于,但它永远不会像你希望的那样起作用。
C和C ++有三种字符类型(“宽”类型除外): char , signed char 和 unsigned char 。普通的 char 可以是签名的或未签名的,这在编译器之间会有所不同。
值 EOF 是一个负整数,通常为-1,因此显然您无法将其存储在 unsigned char 或纯 char < / strong>那是未签名的。假设您的系统使用8位字符(几乎全部都是这样), EOF 将转换为(十进制)255,并且您的程序将无效。
但是如果 char 类型已签名,或者您使用 signed char 类型,那么是,您可以在其中存储-1,所以是的,它可以保持 EOF 。但是当你从文件中读取代码为255的字符时会发生什么呢?它将被解释为-1,即 EOF (假设您的实现使用-1)。所以你的代码不仅会在文件末尾停止读取,而且一旦找到255个字符就会停止读取。
答案 1 :(得分: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_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
来获得一致的结果。 (不过,对于基本字符集的成员来说,你通常是安全的。)