std :: streambuf :: sgetc的范围

时间:2018-05-04 20:43:29

标签: c++ stl

我的代码使用std::streambuf::sgetc()std::streambuf::sbumpc()来逐个字符地读取文件。这些函数返回一个int类型的值,如果有,则表示读取的字符,如果到达文件的末尾,则返回EOFEOF是实现定义的,在大多数实现中都是-1。

每当读取一个字符时(即如果返回的值不是-1),我能确保返回的值在[0 .. 255]范围内吗?

1 个答案:

答案 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

标准要求[char.traits.typedefs/2]

  

[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,但我希望他们能做类似的事情。