为什么在同一输入上调用n次std :: getline()会传递第n个令牌化?

时间:2018-12-21 23:52:17

标签: c++ getline

这是对此问题的公认答案的后续问题:C++ split string by line

在下面的代码中,(功能doSegment()从应答者@billz引用):

#include <iostream>
#include <sstream>
#include <string>

int doSegment( const char *sentence )
{
  std::stringstream ss(sentence);
  std::string to;

  if (sentence != NULL)
  {
    while(std::getline(ss,to,'\n')){
      std::cout << to << std::endl;
    }
  }

  return 0;
}

int main( int argc, char* argv[] )
{
  std::ostringstream oss;
  oss << "hello\nworld" << std::endl << "my" << std::endl << "name" << std::endl << "is nobody";
  doSegment( oss.str().c_str() );
  return 0;
}

...代码的行为与预期完全相同:它将换行符标记在输入字符串上

问题::为什么在同一个输入参数上迭代调用std::getline()会导致存储在输出参数中的 next 标记化?即std::getline()如何跟踪它被称为 n 次并需要传递第(n + 1)个令牌化?

即作为比较,strtok()通过让您传递NULL作为输入参数来做到这一点,以便它知道对其静态局部变量进行操作-但它会修改其输入。 std::getline()的这种示例用法既不需要在第一次迭代后传递NULL作为输入,也不需要修改其输入。

我确实尝试在cppreference和cplusplus上阅读std::getline()的文章,但是他们似乎并没有真正回答这个问题,而且我还没有发现这个问题。

感谢任何能启发我的工作原理的人。

1 个答案:

答案 0 :(得分:2)

如果不确定状态的存储位置,通常可以通过询问“可以修改哪些参数?”来使用简单的经验法则。

对于getline(),您可以看到第一个参数是对流的非常量引用。这就是状态的存储位置(在您的情况下,存储在const对象中)。如果{{1}}将状态存储在其他位置,则流参数将改为引用{{1}}流。

您还可以选中source code