微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 C++ 中读取格式化文本文件时出现问题

如何解决在 C++ 中读取格式化文本文件时出现问题

正式发布我的第一篇文章。我确信 Stack 上有很多答案,但我需要帮助的问题有点具体。所以这里什么都没有......

任务:

我正在做一个小型学校项目,在我的程序的一部分中,我需要读取不同位置的温度测量值,所有这些都来自一个格式化的文本文件文件里面的数据是这样写的:

23/5/2016  
Location 1  
-7,12,-16,20,18,13,6  
9/11/2014  
Location 2  
−1,3,6,10,8  
9/11/2014  
Location 3  
−5,−2,1,2,−1,−4

第一行代表日期,第二行代表地点,第三行代表当天进行的所有测量(摄氏度)。 我为这部分程序编写的代码如下所示:

tok.seekg(0,std::ios::beg);
int i = 0;
double element;
char sign = ',';
while (!tok.eof()) {
  vector_measurements.resize(vector_measurements.size() + 1);
  tok >> vector_measurements.at(i).day >> sign >> vector_measurements.at(i).month >> sign >> vector_measurements.at(i).year >> std::ws;
  std::getline(tok,vector_measurements.at(i).location);
  sign = ',';
  while (tok && sign == ',') {
    tok >> element;
    vector_measurements.at(i).measurements.push_back(element);
    sign = tok.get();
  }
  if (!tok.eof() && !tok) {
    tok.clear();
    break;
  }
  vector_measurements.at(i).SetAverage();
  i++;
}

我展示的代码链接一个类:

struct Data {
  std::string location;
  std::vector<int> measurements;
  int day,month,year;
  double average = 0;

  void SetAverage();
  int GetMinimalTemperature();
  int GetMaximalTemperature();
};

我已经检查并确认文件存在并且流以正确的模式打开,没有任何错误;所有类方法都按预期工作。但问题就在这里。后来数据排序后(成功读取的那部分数据),就无法在屏幕上正确打印数据了。我得到类似的信息:

Location 2
Date: 9/11/2014
Minimal temperature: 0
Maximal temperature: 0
Average temperature: 0

Location 1
Date: 23/5/2016
Minimal temperature: -16
Maximal temperature: 20
Average temperature: 6.57143

;但我希望:

Location 3
----------
Date: 9/11/2014
Minimal temperature: -5
Maximal temperature: 3
Average temperature: -0.75

Location 2
----------
Date: 9/11/2014
Minimal temperature: -1
Maximal temperature: 10
Average temperature: 5.20

Location 1
----------
Date: 23/5/2016
Minimal temperature: -16
Maximal temperature: 20
Average temperature: 6.57143

问题:

位置的顺序很好,因为我是从最低到最高平均温度排序的。但是无论位置的数量如何,第一个位置总是正确的,第二个位置只有零,并且其他所有位置甚至都没有打印在屏幕上。 我需要更改什么才能让我的程序正确读取数据?或者我只是错过了什么?请原谅我犯的任何拼写错误,因为英语不是我的母语。在此先感谢大家,感谢您的帮助!

解决方法

所以问题是您的文本文件中有一些垃圾。我确实相信这些是 \0 字符,但我不确定。它们在 Atom 文本编辑器中显示为 ? 字符。

你很幸运 StackOverflow 没有清理它们,否则没有人能够帮助你。

在我清理完文本文件后,您的代码就可以工作了。您只需要终止循环并在文件结束时删除最后一个项目,我就是这样做的。这不是最佳的,但它有效。

  while (!tok.eof())
  {
    vector_measurements.resize(vector_measurements.size() + 1);
    Data& currentItem = vector_measurements[i];
    tok >> currentItem.day >> sign >> currentItem.month >> sign >> currentItem.year >> std::ws;

    // If the file ends,the data is invalid and the last item can be thrown away
    if (tok.eof())
    {
      vector_measurements.pop_back();
      break;
    }

    std::getline(tok,currentItem.location);
    sign = ',';
    while (tok && sign == ',')
    {
      tok >> element;
      currentItem.measurements.push_back(element);
      sign = tok.get();
    }
    if (!tok.eof() && !tok)
    {
      tok.clear();
      break;
    }
    currentItem.SetAverage();
    i++;
  }

请使用十六进制编辑器检查您的文件并观察奇怪的字符,然后找出如何摆脱它们。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。