如何在 getline 中使用字符串流构造函数

How to use stringstream constructor in getline?

本文关键字:字符串 构造函数 getline      更新时间:2023-10-16

跟进 https://stackoverflow.com/a/1120224/390066。

为什么我不能使用

getline(stringstream(line),cell,','){}

而不是

stringstream lineStream(line); 
getline(lineStream,cell,','){}

更新

我应该澄清我想在循环中使用 getline。

此外,我还应该注意到,我的最初意图是使用 getline 逐行读取文件,并使用新 getline 中的行,该行将划分为",",这更直观。

根据我目前的理解,getline 不是为此而设计的,因为它接受非常量输入并给出常量令牌;因此,getline 不能盲目递归。

正如@James Kanze所示,你可以。

问题是你真的想要吗?
流在表达式结束时被销毁,因此您只从中读取一个单元格。

如果我们在原始问题的上下文中看这个问题:
即您不能在循环中使用它:

std::string       line = /* Init */;
std::stringstream lineStream(line); 
std::string cell;
while(std::getline(lineStream, cell, ','))
{
    // Do stuff with cell.
}

如果将代码放入此上下文中,它将无法按预期工作:

std::string cell;
while(std::getline(std::istringstream(line).flush(), cell, ','))
{
    // Do stuff with cell.
}

由于while()内的表达式每次都会被完全计算。所以你进入一个无限循环,连续读取第一个单元格。

你可以,但它很丑陋:

std::getline( std::istringstream( line ).flush(), cell, ',' );

问题是std::getline采用非常量引用(即合乎逻辑,因为它将修改流),并且您不能使用临时引用初始化非常量引用。 但是,您可以,在其上调用成员函数。 std::istream::flush是会员函数,它返回对它所基于的流的非常量引用被调用(如果该流是std::istringstream,则不做其他任何东西)。

FWIW:你可能会发现:

cell = std::string( line.cbegin(), std::find( line.cbegin(), line.cend(), ',' ) );

效率更高一点。 而且,至少在我看来,更容易阅读和保持。