使用fscanf从带有整数和浮点数的标签文件中读取C ++

时间:2016-06-14 14:56:36

标签: c++

我已经在StackOverflow和其他网站上找了一天左右,我找不到解决问题的方法。有一些是相似的,但我似乎无法使它们工作。

我有一个制表符分隔的.txt文件。一行包含一个标题,之后500行,每行包含一个整数,一个整数,一个浮点数,一个整数和一个整数。我有一个函数应该从每一行读取第一个和第三个值(第一个整数和浮点数)。它跳过了第一行。这是一个do-while循环,因为我需要能够处理不同长度的文件。然而,它陷入了循环。我将它设置为输出均值,但它只是永远输出零。

void HISTS::readMeans(int rnum) {
    int r;
    char skip[500];
    int index = 0; int area = 0; double mean = 0; int min = 0; int max = 0;

    FILE *datafile = fopen(fileName,"r");
    if(datafile == NULL) cout << "No such file!\n";
    else {
            //ignore the first line of the file
            r = fscanf(datafile,"%s\n",skip);
            cout << skip << endl; //just to check

            //this is the problematic code
            do {
                    r = fscanf(datafile,"%d\t%d\t%f\t%d\t%d\n",&index,&area,&mean,&min,&max);
                    cout << mean << " ";
            } while(feof(datafile) != 1)
    }
    fclose(datafile);
}

以下是我正在尝试阅读的格式的示例数据文件:

        Area        Mean        Min        Max
1       262144      202.448     160        687
2       262144      201.586     155        646
3       262144      201.803     156        771

谢谢!

编辑:我说我需要阅读第一个和第三个值,我知道我正在阅读所有这些值。最终我需要存储第一个和第三个值,但为了简洁起见,我删除了那个部分。这个评论并不简短。

3 个答案:

答案 0 :(得分:1)

你应该做C ++风格,

#include <iostream>
#include <fstream>

int main() {
  std::ifstream inf("file.txt");
  if (!inf) { exit(1); }
  int idx, area, min, max;
  double mean;

  while (inf >> idx >> area >> mean >> min >> max) {
    if (inf.eof()) break;
    std::cout << idx << " " << area << " " << mean << " " << min << " " << max << std::endl;
  }
  return 0;
}

是:

1)易于阅读。

2)代码越少,错误发生的可能性就越小。

3)正确处理EOF

虽然我已经离开了第一线的处理,但这取决于你。

答案 1 :(得分:0)

fscanf返回读取的参数数量。因此,如果它返回小于5,你应该退出循环。

答案 2 :(得分:0)

OP最终使用operator>>,这是在C ++中执行此操作的正确方法。但是,对于感兴趣的C读者,发布的代码中存在一些问题:

  • mean被声明为double,但使用错误的格式说明符%f而不是%lf进行了阅读。
  • 第一行未完全阅读,只有第一个令牌Area

实现所需任务的可能方法如下:

r = fscanf(datafile,"%[^\n]\n",skip);
//                    ^^^^^ read till newline

while ( (r = fscanf(datafile,"%d%d%lf%d%d",&index,&area,&mean,&min,&max)) == 5 ) {
    //                             ^^ correct format specifier for double
    // ...
}