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