【问题标题】:Using .clear() in string streams (C++)在字符串流中使用 .clear() (C++)
【发布时间】:2019-08-20 01:49:51
【问题描述】:

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

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();。书中指出:

"inSS.clear(); 中的语句是重置状态所必需的 流,以便后续提取从头开始;这 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);cin 流中提取joe shmo 23lineString 并在最后丢弃/n

inSS.str(lineString); 将字符串流缓冲区初始化为字符串lineString

inSS &gt;&gt; firstName; 将提取joe

inSS &gt;&gt; lastName; 将提取shmo

inSS &gt;&gt; userAge; 将提取23

inSS留空并准备处理下一个输入。

根据how to reuse stringstream

如果您不调用 clear(),则流的标志(如 eof)不会是 重置,导致令人惊讶的行为

这是什么行为? 那么,实际发生了什么以及为什么需要 .clear()?

【问题讨论】:

标签: c++ stringstream


【解决方案1】:

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

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

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

顺便说一句,最好在inSS &gt;&gt; userAge 之后测试if (!inSS) 以检查错误,否则你会继续以变量已经具有的任何值的形式输出“垃圾”值,因为读取尝试失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-29
    • 2011-03-29
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多