Jos*_*eld 10 c++ string iostream language-lawyer
假设我们有一个简单的流:
hello
Run Code Online (Sandbox Code Playgroud)
请注意,\n
文本文件中通常没有额外的内容.现在,以下简单代码显示eof
在提取单个数据后在流上设置该位std::string
.
int main(int argc, const char* argv[])
{
std::stringstream ss("hello");
std::string result;
ss >> result;
std::cout << ss.eof() << std::endl; // Outputs 1
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,我不明白为什么会根据标准发生这种情况(我正在阅读C++ 11 - ISO/IEC 14882:2011(E)).operator>>(basic_stream<...>&, basic_string<...>&)
被定义为表现得像格式化的输入函数.这意味着它构造了一个sentry
对象,它继续吃掉空白字符.在这个例子中,没有,所以sentry
构造完成没有问题.转换为a时bool
,sentry
对象给出true
,因此提取器继续继续实际提取字符串.
然后将提取定义为:
提取并附加字符,直到出现以下任何一种情况:
n
字符存储;- 文件结束发生在输入序列上;
isspace(c,is.getloc())
对于下一个可用的输入字符c,则为true .在提取最后一个字符(如果有)之后,调用is.width(0)并销毁sentry对象k.如果函数没有提取任何字符,则会调用
is.setstate(ios::failbit)
,这可能会抛出ios_base::failure
(27.5.5.4).
这里没有任何东西实际上导致该eof
位被设置.是的,如果提取到达文件结尾,则提取停止,但它不会设置该位.事实上,eof
只有当我们做另一个时才应该设置该位ss >> result;
,因为当sentry
尝试吞噬空白时,会发生以下情况:
如果
is.rdbuf()->sbumpc()
或is.rdbuf()->sgetc()
返回traits::eof()
,则函数调用setstate(failbit | eofbit)
但是,这肯定没有发生,因为failbit
没有设置.
eof
设置位的结果是,while (!stream.eof())
在读取文件时邪恶习惯不起作用的唯一原因是因为\n
最后的额外而不是因为该eof
位尚未设置.eof
当提取在文件末尾停止时,我的编译器很乐意设置该位.
这应该发生吗?或者标准是否意味着setstate(eofbit)
应该发生?
为方便起见,标准的相关部分是:
basic_istream::sentry
[istream :: sentry]std::stringstream
是basic_istream
和operator>>
的std::string
从中"提取物"的字符(如你发现了).
27.7.2.1类模板 basic_istream
2如果rdbuf() - > sbumpc()或rdbuf() - > sgetc()返回traits :: eof(),则输入函数除非另有明确说明,否则完成其操作并执行setstate(eofbit),在返回之前抛出ios_- base :: failure(27.5.5.4).
此外,"提取"意味着调用这两个函数.
3两组成员函数签名共享公共属性:格式化的输入函数(或提取器)和未格式化的输入函数.两组输入函数都被描述为通过调用rdbuf() - > sbumpc()或rdbuf() - > sgetc()来获取(或提取)输入字符.他们可能会使用istream的其他公共成员.
所以必须设置eof.
归档时间: |
|
查看次数: |
1122 次 |
最近记录: |