标准范围::流::SGETC
Range of std::streambuf::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 -1
,char_traits<char>::to_int_type(c)
的相应有效实现是return (unsigned char)c
。
我检查了一下,stdlibc++和libc++都是这样做的。不幸的是,我无法检查 MSVC,但我希望他们能做类似的事情。
- 使用CMake检测支持的C++标准
- 如何理解C++标准N3337中的expr.const.cast子句8
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 编译标准库类型
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 铸造标准::有没有回到原来的类型
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 标准库类型的赋值运算符的引用限定符
- 标准是否严格定义了该程序应该如何编译?
- 如何从Windows应用程序输出到标准?
- 安全到标准:移动会员?
- 如何正确将字符串转换为标准::时间::system_clock::time_point?
- 这是否符合C++标准:双响双响,例如!!(-0.0).
- 标准::变体的赋值运算符
- 捕获标准输出以压缩并使用 CTRL-C 中断会给出损坏的 zip 文件
- 如何在 Mac 上使用 c++17 并行标准库算法?
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- 标准范围::流::SGETC