这是我的教科书中有关使用/实现字符串流的示例:
int main() {
istringstream inSS; // Input string stream
string lineString; // Holds line of text
string firstName; // First name
string lastName; // Last name
int userAge = 0; // Age
bool inputDone = false; // Flag to indicate next iteration
// Prompt user for input
cout << "Enter \"firstname lastname age\" on each line" << endl;
cout << "(\"Exit\" as firstname exits)." << endl << endl;
// Grab data as long as "Exit" is not entered
while (!inputDone) {
// Entire line into lineString
getline(cin, lineString);
// Copies to inSS's string buffer
inSS.clear(); // <-- HELLO RIGHT HERE
inSS.str(lineString);
// Now process the line
inSS >> firstName;
// Output parsed values
if (firstName == "Exit") {
cout << " Exiting." << endl;
inputDone = true;
}
else {
inSS >> lastName;
inSS >> userAge;
cout << " First name: " << firstName << endl;
cout << " Last name: " << lastName << endl;
cout << " Age: " << userAge << endl;
cout << endl;
}
}
return 0;
}
我不明白为什么需要
inSS.clear();
。该书指出:.clear()
所做的全部是“set a new value for the stream's internal error state flags.”时,如何使下一提取从头开始?如果我从上面的示例中删除了
inSS.clear()
语句,它将无法正常工作。例如:输入:
joe shmo 23
alex caruso 21
输出:
First name: joe
Last name: shmo
Age: 23
First name: joe
Last name: shmo
Age: 23
这是我期望删除
inSS.clear()
语句时发生的事情。我的理解显然有缺陷,所以请纠正我:输入:
joe shmo 23
alex caruso 21
getline(cin, lineString);
从joe shmo 23
流中提取cin
到lineString
中,并在最后丢弃/n
。inSS.str(lineString);
将字符串流缓冲区初始化为字符串lineString
。inSS >> firstName;
将提取joe
inSS >> lastName;
将提取shmo
inSS >> userAge;
将提取23
将
inSS
留空并准备处理下一个输入。根据how to reuse stringstream
这是什么行为?
那么,实际上会发生什么,为什么需要.clear()?
最佳答案
第一次执行inSS >> userAge;
后,这涉及尝试读取字符串的末尾,因为它必须查看年龄的最后一位数字之后是否还有另一位数字。
这意味着在流上设置了eofbit
,这意味着由于流处于文件结束状态,将来的提取将失败。 clear()
调用清除此状态。
您应该发现,如果您第一次提供一个输入字符串就可以提取userAge
而无需结尾(例如joe shmo 23 foo
),那么就不需要clear()
调用了(但这仍然是一个好习惯)。
顺便说一句,在if (!inSS)
之后测试inSS >> userAge
以检查是否有错误是个好习惯,否则您将以变量已具有的任何值的形式继续输出“垃圾”值,因为读取尝试失败。