为什么在同一输入上调用std::getline()n次会产生第n个标记化

Why does calling std::getline() n times on the same input deliver the nth tokenization?

本文关键字:输入 调用 为什么 getline std      更新时间:2023-10-16

这是这个问题的已接受答案的后续问题:C++按行拆分字符串

在以下代码中,(函数doSegment()引用自answerer@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 << "hellonworld" << std::endl << "my" << std::endl << "name" << std::endl << "is nobody";
doSegment( oss.str().c_str() );
return 0;
}

代码的行为完全符合预期:它在换行上标记输入字符串

问题:为什么对同一输入参数迭代调用std::getline()会导致存储到输出参数的下一个标记化?即,std::getline()如何跟踪它被调用n次,并需要交付第(n+1)个标记化?

也就是说,作为比较,strtok()通过将NULL作为输入参数进行传递来实现这一点,这样它就知道要对其静态局部变量进行操作,但它会修改其输入。std::getline()的示例使用既不需要在第一次迭代后传递NULL作为输入,也不修改其输入。

我确实试着在cppresence和cplusplus上阅读了std::getline()的文章,但他们似乎并没有真正回答这个问题,我也没有发现这个问题已经存在了。

感谢任何能启发我这是如何运作的人。

当您不确定状态存储在哪里时,通常可以使用简单的经验法则,询问"可以修改哪些参数?"。

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

您也可以检查源代码。