这是我的教科书中有关使用/实现字符串流的示例:

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流中提取cinlineString中,并在最后丢弃/n
inSS.str(lineString);将字符串流缓冲区初始化为字符串lineString
inSS >> firstName;将提取joeinSS >> lastName;将提取shmoinSS >> userAge;将提取23
inSS留空并准备处理下一个输入。

根据how to reuse stringstream



这是什么行为?
那么,实际上会发生什么,为什么需要.clear()?

最佳答案

第一次执行inSS >> userAge;后,这涉及尝试读取字符串的末尾,因为它必须查看年龄的最后一位数字之后是否还有另一位数字。

这意味着在流上设置了eofbit,这意味着由于流处于文件结束状态,将来的提取将失败。 clear()调用清除此状态。

您应该发现,如果您第一次提供一个输入字符串就可以提取userAge而无需结尾(例如joe shmo 23 foo),那么就不需要clear()调用了(但这仍然是一个好习惯)。

顺便说一句,在if (!inSS)之后测试inSS >> userAge以检查是否有错误是个好习惯,否则您将以变量已具有的任何值的形式继续输出“垃圾”值,因为读取尝试失败。

10-02 01:06