C++从istream读取直到换行符(但不包括空格)

19

我有一个指向矩阵数据的std::istream,例如:

0.0 1.0 2.0
3.0 4.0 5.0

现在,为了评估所需的列数,我想要一些类似以下代码的东西:

std::vector<double> vec;
double x;
while( (...something...) && (istream >> x) )
{
    vec.push_back(x); 
}
//Here vec should contain 0.0, 1.0 and 2.0

当我读取2.0并且`istream`在该点处为3.0时,where the ...something... part的评估结果为false,因此下一个操作没有被执行。

istream >> x;

应该将x设置为3.0。

您如何实现这个结果?我猜while条件

非常感谢您的帮助!


只是为了澄清,我想采用这种方法(如果可行)的原因是避免创建临时对象(除了双倍x)。然后通过将上面的向量与矩阵内部存储进行std::swap来创建矩阵(它是通过std::vector实现的)。 - StephQ
好的,你可以用10行简单的代码使用一个临时变量来完成它,或者你可以用50行复杂的代码不使用临时变量。建议使用临时变量。 - Mooing Duck
6个回答

14

使用peek方法来检查下一个字符:

while ((istream.peek()!='\n') && (istream>>x))

5
如果在 <换行符> 之前有 任何 空格,那么这很容易被打破。 - Clifford
真的;这里没有任何错误检查,我只是假设输入是格式良好的。 - tzaman

12

使用 std::getline() 将文本行读入 std::string 中,然后将字符串赋值给 std::istringstream 对象,并从该对象中提取数据,而不是直接从 istream 中提取。


抱歉,我之前没有表达清楚,但这就是我想要避免的。问题在于我事先不知道矩阵会有多少列或多少行,而将字符串存储10,000个双精度浮点数并不是解决问题的有效方法 :) 再次对我的表述不够清晰表示抱歉,这是我的错。 - StephQ

3
std::vector<double> vec;
{
   std::string line;
   std::getline( ifile, line );
   std::istringstream is(line);
   std::copy( std::istream_iterator<double>(is), std::istream_iterator<double>(),
              std::back_inserter(vec) );
}
std::cout << "Input has " << vec.size() << " columns." << std::endl;
std::cout << "Read values are: ";
std::copy( vec.begin(), vec.end(), 
           std::ostream_iterator<double>( std::cout, " " ) );
std::cout << std::endl;

OP明确指出不想先缓存整行数据。 - tzaman
他的提议代码要求在 while 后,向量应包含第一行://Here vec should contain 0.0, 1.0 and 2.0。他是不是不想读取一行或整个文件? - David Rodríguez - dribeas
是的,我想在读取第一行后结束while循环(并将其余内容保留在istream中以供进一步阅读),但我希望避免创建一个字符串来存储整个第一行,然后再将其放入向量中。 - StephQ

1
你可以使用 std::istream::peek() 来检查下一个字符是否为换行符。 请参阅 cplusplus.com 参考文献中的 this entry

0

我遇到了类似的问题
输入如下:

1 2
3 4 5

第一和第二个是N1和N2
然后是一个换行符
接下来是3、4、5元素,我不知道会有多少个。
// read N1 & N2 using cin
int N1, N2;
cin >> N1;
cin >> N2;

// skip the new line which is after N2 (i.e; 2 value in 1st line)
cin.ignore(numeric_limits<streamsize>::max(), '\n');

// now read 3 4 5 elements
int ele;
// 2nd EOF condition may required,
//    depending on if you dont have last new-line, and it is end of file.
while ((cin_.peek() != '\n') && (cin_.peek() != EOF)) {
  cin >> ele;
  // do something with ele
}

这对我来说完美地运作了。


0

读取数字, 然后读取一个字符来判断它是否为换行符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接