while(getline())和while(!getline()。eof())之间有什么区别?
Am解析输入字符串。 我尝试了两种条件检查,但结果却有所不同。
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结果: 您好:CN 测试,OU XYZ,O ABC
Ex B结果: 您好:CN 测试,OU XYZ,O
答案 0 :(得分:1)
参考号:CppReference.com, "iostate"
getline()
返回对其进行操作的流的引用,即inpStrStream
。
inpStrStream.operator bool()
(或while ( inpStrStream )
/ while ( getline( inpStrStream, tempStr, '=' ) )
)将检查是否已设置流的failbit
或badbit
。
! inpStrStream.eof()
将检查是否设置了流的eofbit
。 (*)
CppReference状态,
...在几乎所有情况下,如果设置了
eofbit
,那么也设置了failbit
。
您在这里遇到了例外之一。 .operator!()
检查failbit
,对eofbit
进行否验证-getline()
中的"ABC"
确实设置了eofbit
( (到达流的EOF时),但不failbit
(因为最后一次操作仍然成功)。这使.eof()
结束循环(不打印"ABC"
),而.operator!()
将再执行一次迭代(打印"ABC"
),尝试执行另一个getline()
,但失败(因为没有更多内容可供阅读),设置failbit
并结束循环。
所以... .eof()
将明确地测试EOF,仅 ,即即使基础流发生了令人讨厌的事情,它也会尝试继续得到另外两个标志之一。
(*):请注意,还有更多测试。唯一对称的是.fail()
和.operator!()
(它们测试相同的事物),并且它们的对称相反的.operator bool()
。其他.good()
,.bad()
和.eof()
分别检查不同的事物!
答案 1 :(得分:0)
看看这个简单的测试代码:
#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());
char ch = '?';
input >> ch;
LOG(!!input);
LOG(input.eof());
LOG(ch);
}
int main()
{
test('!');
std::cout << '\n';
test('#');
return 0;
}
及其输出:https://wandbox.org/permlink/r4OSFnkG3ZFETgd4
14: !!input = 1
15: input.eof() = 0
19: !!input = 0
20: input.eof() = 1
21: ch = ?
14: !!input = 1
15: input.eof() = 1
19: !!input = 0
20: input.eof() = 1
21: ch = ?
eof
并不意味着您处于流的结尾,而是您试图读取超出其大小的流。test
getline
的第二次运行成功(!!input
),但是尝试读取超出流大小的数据,因此eof
返回true
。现在,与eof
的循环可以拒绝对您来说很重要的事情,因为eof
设置为true
,但是阅读很成功。答案 2 :(得分:0)
类std::stringstream
继承了定义操作符的类std::basic_ios
explicit operator bool() const;
那个
1返回:!fail()。
该操作符用于while语句的情况
while(getline(inpStrStream, tempStr, '='))
根据上下文将std::getline
调用返回的对象转换为bool类型。
来自C ++标准(C ++ 17、7标准转换)
4某些语言构造要求将表达式转换 为布尔值。在这种情况下出现的表达式e是 据说可以根据上下文转换为bool,并且如果且 仅当声明bool t(e)时;格式良好,对于某些发明 临时变量t(11.6)。