C++ 如何在getline中使用stringstream构造函数?
后续行动 为什么我不能用C++ 如何在getline中使用stringstream构造函数?,c++,stream,getline,default-constructor,C++,Stream,Getline,Default Constructor,后续行动 为什么我不能用 getline(stringstream(line),cell,','){} 而不是 stringstream lineStream(line); getline(lineStream,cell,','){} ? 更新 我应该澄清一下,我想在循环中使用getline 此外,我还应该注意到,我最初的意图是使用getline逐行读取文件,并使用新getline中的行,该行将在“,”上划分,这在我看来更直观 据我目前所知,getline并不是为此而设计的,因为它接受非常
getline(stringstream(line),cell,','){}
而不是
stringstream lineStream(line);
getline(lineStream,cell,','){}
?
更新
我应该澄清一下,我想在循环中使用getline
此外,我还应该注意到,我最初的意图是使用getline逐行读取文件,并使用新getline中的行,该行将在“,”上划分,这在我看来更直观
据我目前所知,getline并不是为此而设计的,因为它接受非常量输入并提供常量令牌;因此,getline不能盲目递归 你可以,但它很难看:
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(), ',' ) );
效率高一点。而且,至少在我看来,更容易阅读和理解
维护。如@James Kanze所示,您可以 问题是你真的想要吗?
该流在表达式末尾被销毁,因此您只能从中读取一个单元格 如果我们从以下方面来看:
i、 e.您不能在循环中使用:
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()
中的表达式每次都将被完全计算。因此,您进入一个infinte循环,连续读取第一个单元格。getline将更改一些临时对象,这些临时对象始终保持不变。将值存储在一个临时变量中是否有任何意义…定义模板T&stay(T&&x){return x;}
并尝试:std::getline(stay(std::istringstream(line)),cell,“,”)
@KerrekSB-Neat,除了名称:-),这表明它以某种方式延长了临时文件的生命周期。(使用flush()。两者都没有改变事物的位置:-)也许它们应该被重命名为std::value\u category\u cast
!他可能想。如果他使用的是getline
,那么使用std::find
或std::find_If
有更有效、更自然的方法来实现这一点;不过,它可能有助于提取初始数值。(总的来说,和你一样,我也持怀疑态度。通常情况下,你会想在提取后检查状态。但我肯定会有这样的情况。)@JamesKanze:有更有效的方法。但这对我来说是很自然的。使用std::find()
更像C,需要更多的辅助代码才能到达同一点。因此,这项技术很容易教授,因为所有的细节都为您处理,而您可以专注于结果。