【问题标题】:C++ read from istream until newline (but not whitespace)C++ 从 istream 读取直到换行(但不是空格)
【发布时间】:2011-03-16 20:29:15
【问题描述】:

我有一个引用矩阵数据的 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 后 ...something... 部分的计算结果为 false,此时 istream 应为 3.0,以便下一个

istream >> x;

应该设置 x 等于 3.0。

您将如何实现这一结果?我猜是while条件

非常感谢您的帮助!

【问题讨论】:

  • 澄清一下,我想采用这种方法(如果可行的话)的原因是为了避免创建临时对象(除了双 x)。然后通过 std::swap 创建矩阵 - 将上面的向量与矩阵内部存储(它通过 std::vector 实现)。
  • 嗯,你可以用 10 行简单的临时代码来完成,或者你可以不用 50 行的临时代码来完成。使用临时的。

标签: c++ iostream


【解决方案1】:

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

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

【讨论】:

  • 如果该行在 之前包含 any 空格,这很容易被破坏
  • 真;这里根本没有错误检查,我只是假设输入格式正确。
【解决方案2】:

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

【讨论】:

  • 对不起,我没有说清楚,但这是我试图避免的。关键是我事先不知道矩阵是否会有很多列或很多行,并且字符串存储 10.000 双精度不是解决问题的一种非常有效的方法:) 再次抱歉,我的错没有说清楚。跨度>
【解决方案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 特别提到不想先缓冲一整行。
  • 他提议的代码要求在 while 之后向量应该包含第一行://Here vec should contain 0.0, 1.0 and 2.0。他不想读一行或整个文件吗?
  • 是的,我想在读取第一行后结束 while 循环(并将其余部分保留在 istream 中以供进一步阅读),但我想避免创建一个字符串来存储第一个整体在将其放入向量之前的行。
【解决方案4】:

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

【讨论】:

    【解决方案5】:

    读取数字,然后读取一个字符,看看它是否是换行符。

    【讨论】:

      【解决方案6】:

      我有类似的问题
      输入如下:

      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
      }
      

      这对我来说很完美。

      【讨论】:

        猜你喜欢
        • 2017-10-18
        • 2010-12-21
        • 1970-01-01
        • 1970-01-01
        • 2012-03-03
        • 1970-01-01
        • 2023-03-24
        • 2011-02-23
        • 1970-01-01
        相关资源
        最近更新 更多