在字符串流中使用 .clear() (C++)
Using .clear() in string streams (C++)
这是我教科书中关于使用/实现字符串流的示例:
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();
是必要的。书中指出:
"The statement inSS.clear(); is necessary to reset the state of the
stream so that subsequent extractions start from the beginning; the
clear resets the stream's state."
当它所做的只是“set a new value for the stream's internal error state flags.”时,.clear()
如何导致下一次提取从头开始?
如果我从上面的示例中删除 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);
从 cin
流中提取 joe shmo 23
到 lineString
并在最后丢弃 /n
。
inSS.str(lineString);
将字符串流缓冲区初始化为字符串 lineString
。
inSS >> firstName;
将提取 joe
inSS >> lastName;
将提取 shmo
inSS >> userAge;
将提取 23
将 inSS
留空并准备好处理下一个输入。
根据how to reuse stringstream
If you don't call clear(), the flags of the stream (like eof) wont be
reset, resulting in surprising behaviour
这是什么行为?
那么,实际发生了什么以及为什么需要 .clear()?
在您第一次执行 inSS >> userAge;
之后,这涉及尝试读取字符串的末尾,因为它必须查看在年龄的最后一位数字之后是否还有另一位数字。
这意味着在流上设置了 eofbit
,这意味着由于流处于文件结束状态,未来的提取将失败。 clear()
调用清除此状态。
您应该会发现,如果您第一次提供的输入字符串可以提取 userAge
而不会结束(例如 joe shmo 23 foo
),那么 clear()
调用就没有必要了(但这仍然是个好习惯)。
顺便说一句,最好在 inSS >> userAge
之后测试 if (!inSS)
以检查错误,否则你会继续以变量已经具有的任何值的形式输出 "garbage" 值,因为读取尝试失败。
这是我教科书中关于使用/实现字符串流的示例:
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();
是必要的。书中指出:
"The statement inSS.clear(); is necessary to reset the state of the stream so that subsequent extractions start from the beginning; the clear resets the stream's state."
当它所做的只是“set a new value for the stream's internal error state flags.”时,.clear()
如何导致下一次提取从头开始?
如果我从上面的示例中删除 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);
从 cin
流中提取 joe shmo 23
到 lineString
并在最后丢弃 /n
。
inSS.str(lineString);
将字符串流缓冲区初始化为字符串 lineString
。
inSS >> firstName;
将提取 joe
inSS >> lastName;
将提取 shmo
inSS >> userAge;
将提取 23
将 inSS
留空并准备好处理下一个输入。
根据how to reuse stringstream
If you don't call clear(), the flags of the stream (like eof) wont be reset, resulting in surprising behaviour
这是什么行为? 那么,实际发生了什么以及为什么需要 .clear()?
在您第一次执行 inSS >> userAge;
之后,这涉及尝试读取字符串的末尾,因为它必须查看在年龄的最后一位数字之后是否还有另一位数字。
这意味着在流上设置了 eofbit
,这意味着由于流处于文件结束状态,未来的提取将失败。 clear()
调用清除此状态。
您应该会发现,如果您第一次提供的输入字符串可以提取 userAge
而不会结束(例如 joe shmo 23 foo
),那么 clear()
调用就没有必要了(但这仍然是个好习惯)。
顺便说一句,最好在 inSS >> userAge
之后测试 if (!inSS)
以检查错误,否则你会继续以变量已经具有的任何值的形式输出 "garbage" 值,因为读取尝试失败。