我的代码使用std::streambuf::sgetc()
和std::streambuf::sbumpc()
来逐个字符地读取文件。这些函数返回一个int类型的值,如果有,则表示读取的字符,如果到达文件的末尾,则返回EOF
。 EOF
是实现定义的,在大多数实现中都是-1。
每当读取一个字符时(即如果返回的值不是-1),我能确保返回的值在[0 .. 255]范围内吗?
答案 0 :(得分:1)
标准不保证这一点,但你可能会认为结果是有效的char
,因为每个人都这样做。
如果您想绝对确定,请使用std::char_traits<char>::to_char_type
转换回char
。然后,标准保证您收到原始值,该值适合char
。
std::streambuf
本质上是std::basic_streambuf<char, std::char_traits<char>>
的快捷方式。 sbumpc()
和sgetc()
返回的整数类型是此traits类的int_type
。
[f]或某个字符容器类型
char_type
,相关的容器类型INT_T
应该是一个类型或类,它可以表示从相应的char_type
转换的所有有效字符值,以及文件结束值eof()
。类型int_type
表示一个字符容器类型,它可以保存文件结尾,以用作iostream类成员函数的返回类型。
基本上,int_type
需要包含所有可能的字符,并且需要一个单独的EOF值。
以下是[streambuf.pub.get]中<{1}}成员函数的定义方式:
std::streambuf
返回:如果输入序列读取位置不可用,则返回
int_type sbumpc();
。否则,返回uflow()
并递增输入序列的下一个指针。
traits::to_int_type(*gptr())
返回:如果输入序列读取位置不可用,则返回
int_type sgetc();
。否则,返回underflow()
。
最终,它归结为标准库如何实现traits::to_int_type(*gptr())
,标准对此的要求非常少(参见[char.traits.require]中的表56)。至少理论上可能字符被映射到原始字符的范围之外。
然而,我不知道任何实际执行此操作的库实现 - 大多数只是使用更大的整数类型,因此他们可以返回std::char_traits<char>::to_int_type
EOF,但保留所有字符相同(它也可能是实现这一目标的最有效方式)。有一个原因,cppreference.com explicitly mentions
-1
的常见实现是char_traits<char>::eof()
,return -1
的相应有效实施是char_traits<char>::to_int_type(c)
。
我检查过,stdlibc ++和libc ++都这样做。不幸的是,我无法检查MSVC,但我希望他们能做类似的事情。