提问人:Pravinkumar 提问时间:7/2/2019 更新时间:7/16/2022 访问量:582
在 getline 上检查 eof() 即 while(!getline().eof()) 和简单地检查 while(getline()) 有什么区别
What is difference in checking eof() on getline i.e. while(!getline().eof()) and checking simply while(getline())
问:
while(getline()) 和 while(!getline().eof()) 和有什么不一样?
正在解析输入字符串。 我已经尝试了两种条件检查,我看到了结果的差异。
std::string testStr = "CN=Test, OU=XYZ, O=ABC";
std::stringstream inpStrStream(testStr);
std::string tempStr;
getline(inpStrStream, tempStr, '=');
std::cout<<"Hello:"<<tempStr<<std::endl;
//Let's call this as "Ex A"
while(getline(inpStrStream, tempStr, '='))
{
std::cout<<tempStr<<std::endl;
}
(OR)
//Let's call this as "Ex B"
while(!getline(inpStrStream, tempStr, '=').eof())
{
std::cout<<tempStr<<std::endl;
}
我期望两者的结果相同,但“Ex A”和“Ex B”的结果不同。我在“Ex B”的输出中没有看到字符串“ABC”:
Ex A 结果: 您好:CN 测试、OU XYZ,O 美国广播公司
Ex B 结果: 您好:CN 测试、OU XYZ,O
答:
getline()
返回它所操作的流的引用,即 .inpStrStream
inpStrStream.operator bool()
(或 / ) 将检查是否设置了流的 或。while ( inpStrStream )
while ( getline( inpStrStream, tempStr, '=' ) )
failbit
badbit
! inpStrStream.eof()
将检查是否设置了流。(*)eofbit
CppReference 状态,
...在几乎所有情况下,如果被设置,也被设置。
eofbit
failbit
您在这里遇到了一个例外。 检查 ,而不是 -- -- ant that of does set(当到达流的 EOF 时),但不检查 failbit
(因为最后一个操作仍然成功)。这使得结束循环(不是打印),而将再进行一次迭代(打印),尝试另一次,但失败(因为没有更多可读取的内容),设置并结束循环。.operator!()
failbit
eofbit
getline()
"ABC"
eofbit
.eof()
"ABC"
.operator!()
"ABC"
getline()
failbit
所以。。。 将仅显式测试 EOF,即即使底层流发生了一些令人讨厌的事情,并且确实设置了其他两个标志之一,也会尝试继续。.eof()
(*):请注意,还有更多测试。唯一对称的是 和 (它们测试相同的事物),以及它们的对称相反 。其他人-- , ,和--检查不同的东西!.fail()
.operator!()
.operator bool()
.good()
.bad()
.eof()
评论
inpStrStream.operator!()
inpStrStream.eof()
operator!()
operator bool()
getline()
getline()
while ()
.operator bool()
! failbit && ! badbit
! (/*stream*/).eof()
! eofbit
看看这个简单的测试代码:
#include <iostream>
#include <sstream>
#define LOG(x) std::cout << __LINE__ << ": " #x " = " << x << '\n'
void test(char termChar)
{
std::stringstream input;
input << "lets try this!";
std::string s;
std::getline(input, s, termChar);
LOG(!!input);
LOG(input.eof());
LOG(input.tellg());
char ch = '?';
input >> ch;
LOG(!!input);
LOG(input.eof());
LOG(input.tellg());
LOG(ch);
}
int main()
{
test('!');
std::cout << '\n';
test('#');
return 0;
}
其输出:https://godbolt.org/z/f55eTjWK1
14: !!input = 1
15: input.eof() = 0
16: input.tellg() = 14
20: !!input = 0
21: input.eof() = 1
22: input.tellg() = -1
23: ch = ?
14: !!input = 1
15: input.eof() = 1
16: input.tellg() = -1
20: !!input = 0
21: input.eof() = 1
22: input.tellg() = -1
23: ch = ?
- 记住并不意味着您处于流的末尾,而是您尝试读取超出其大小的流。
eof
- 现在在第二次运行中成功 (),但尝试读取超出流大小,因此返回。现在你的循环可以拒绝对你来说重要的事情,因为设置为,但阅读是成功的。
test
getline
!!input
eof
true
eof
eof
true
该类继承定义运算符的类std::stringstream
std::basic_ios
explicit operator bool() const;
那
1 返回:!fail()。
此运算符用于 while 语句的条件
while(getline(inpStrStream, tempStr, '='))
在上下文中将调用 of 返回的对象转换为 bool 类型。std::getline
从 C++ 标准(C++ 17,7 标准转换)
4 某些语言结构要求转换表达式 设置为布尔值。在这样的上下文中出现的表达式 e 是 据说在上下文中转换为布尔值,并且格式良好,如果和 仅当声明 bool t(e);格式良好,对于一些发明的 临时变量 t (11.6)。
评论
ABC
tempStr