标准范围::流::SGETC



我的代码使用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 -1char_traits<char>::to_int_type(c)的相应有效实现是return (unsigned char)c

我检查了一下,stdlibc++和libc++都是这样做的。不幸的是,我无法检查 MSVC,但我希望他们能做类似的事情。

最新更新