我不明白 std::stream 中的 std::string

I do not understand std::string from std::stream

提问人:troppapolvere 提问时间:10/5/2022 最后编辑:KompjoeFriektroppapolvere 更新时间:10/6/2022 访问量:51

问:

尽管我害怕显得很愚蠢,但我想问为什么这个程序:

#include <iostream>
#include <fstream>

int main(int argc, char * argv[]) {

  std::ifstream fitData("./fitData.txt");

  int line=1;
  while (true) {
    std::string compType;
    bool isRS;
    int dRecMode;
    double mass;
    fitData >> compType >> isRS >> dRecMode >> mass;
    if ( fitData.eof() ) break;
    std::cout << "at line: " << line << ":" << compType << " " << isRS << " " << dRecMode << " " << mass << std::endl;

    line++;

    if ( line > 20 ) break;
  }

  std::cout << line << std::endl;
}

在此文件上运行时:

prompt> cat fitData.txt 
TT: 1 7 2.26455
TT: 1 7 2.45204
TT: 1 1 2.05438
TT: 1 -5 2.36097
TT: 1 -5 2.34911
TT: 1 7 2.43344
TT: 1 3 2.5
TT: 1 1 2.34866
TT: 1 2 2.24831
TT: 1 -3 2.31099
LC: 0 99 2.27828
LC: 1 99 2.29757
LC: 2 99 2.27512
LC: 3 99 2.31149
LC: 4 99 2.31205
LC: 5 99 2.31091

进入一个无休止的循环:

at line: 1:TT: 1 7 2.26455
at line: 2:TT: 1 7 2.45204
at line: 3:TT: 1 1 2.05438
at line: 4:TT: 1 -5 2.36097
at line: 5:TT: 1 -5 2.34911
at line: 6:TT: 1 7 2.43344
at line: 7:TT: 1 3 2.5
at line: 8:TT: 1 1 2.34866
at line: 9:TT: 1 2 2.24831
at line: 10:TT: 1 -3 2.31099
at line: 11:LC: 0 99 2.27828
at line: 12:LC: 1 99 2.29757
at line: 13:LC: 1 99 2.29757
at line: 14: 1 99 2.29757
at line: 15: 1 99 2.29757
at line: 16: 1 99 2.29757
at line: 17: 1 99 2.29757
at line: 18: 1 99 2.29757
at line: 19: 1 99 2.29757
at line: 20: 1 99 2.29757
21

它发生在我能够接触到的每台机器上:MSWin10(64 位)上的 WSL2、Win7(32 位)上的 cygwin,最后是纯 Linux(Xubuntu-64 位)。 在第二次运行时,出现问题,std::string 看起来是空的。

非常感谢您的见解!即使有人劝诫你去做计算以外的事情!:-)

std stdstring

评论

0赞 KompjoeFriek 10/5/2022
如果可以读取文件“./fitData.txt”,则此代码将始终读取 10 行(或至少尝试读取),然后打印始终为 11 行。请在您的循环中检查linefitDatawhile
0赞 troppapolvere 10/5/2022
答案是肯定的。。。。一条线丢失了.....给我一些时间来纠正我的帖子。
0赞 troppapolvere 10/5/2022
完成后,我希望现在我的问题更有意义.....不好意思!

答:

0赞 KompjoeFriek 10/6/2022 #1

似乎在您尝试读入 .LC: 2 99 2.275122bool

在这种情况下,您可以通过设置异常掩码来引发异常,然后在尝试读取后捕获异常。ifstream

#include <iostream>
#include <fstream>

int main(int argc, char * argv[]) {
  std::ifstream fitData("./fitData.txt");
  fitData.exceptions(std::ifstream::failbit | std::ifstream::badbit);
  int line=0;
  if (fitData.is_open()) {
    while (line < 20) {
      std::string compType;
      bool isRS;
      int dRecMode;
      double mass;
      try {
        fitData >> compType >> isRS >> dRecMode >> mass;
      } catch (std::system_error& e) {
        std::cout << e.what() << std::endl;
        break;
      }
      line++;
      std::cout << "at line: " << line << ":" << compType << " " << isRS << " " << dRecMode << " " << mass << std::endl;
    }
  }

  std::cout << line << std::endl;
}

输出:

at line: 1:TT: 1 7 2.26455
at line: 2:TT: 1 7 2.45204
at line: 3:TT: 1 1 2.05438
at line: 4:TT: 1 -5 2.36097
at line: 5:TT: 1 -5 2.34911
at line: 6:TT: 1 7 2.43344
at line: 7:TT: 1 3 2.5
at line: 8:TT: 1 1 2.34866
at line: 9:TT: 1 2 2.24831
at line: 10:TT: 1 -3 2.31099
at line: 11:LC: 0 99 2.27828
at line: 12:LC: 1 99 2.29757
basic_ios::clear: iostream error
12

在线试用!

或者,您可以只检查流是否在阅读后仍然。good()