【问题标题】:How to use stringstream constructor in getline?如何在 getline 中使用 stringstream 构造函数?
【发布时间】:2015-01-14 17:42:54
【问题描述】:

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

为什么我不能使用

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

而不是

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

?

更新

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

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

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

【问题讨论】:

  • getline 会更改一些临时对象,该对象将始终保持不变。
  • 将值存储在临时变量中是否有任何意义...
  • 定义 template <typename T> T & stay(T && x) { return x; } 并尝试:std::getline(stay(std::istringstream(line)), cell, ',')
  • @KerrekSB Neat,除了名称:-),这表明它以某种方式延长了临时的生命周期。 (flush() 的使用是神圣的习语,虽然我也不会说它特别透明。但它确实适用于 C++11 之前的版本。)
  • @JamesKanze:staymove 的反义词。两者都没有真正改变事物的位置 :-) 也许它们应该重命名为 std::value_category_cast!

标签: c++ stream getline default-constructor


【解决方案1】:

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

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

如果我们在context of the original question 中查看此内容:
即你不能在循环中使用它:

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() 中的表达式每次都会被完全评估。所以你进入一个无限循环连续读取第一个单元格。

【讨论】:

  • 他可能想要。如果他正在使用getline,那么使用std::findstd::find_if 有更高效、更自然的方法;但是,它可能对选取初始数值很有用。 (总的来说,我和你一样持怀疑态度。通常情况下,你会想在提取后检查状态。但我相信有案例。)
  • @JamesKanze:有更有效的方法。但这对我来说很自然。使用std::find() 更像C,并且需要更多的辅助代码才能达到相同的目的。因此,这项技术很容易教授,因为所有细节都已为您处理好,而您可以专注于结果。
【解决方案2】:

可以,但是很丑:

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(), ',' ) );

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 2018-02-20
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多