fseek和fscan在C ++中给出了.DAT文件的错误结果

时间:2017-02-20 21:53:10

标签: c++ fopen scanf fseek fgetc

我有一个不断更新的.dat文件。我想从文件中的最新行获取数据。但是我获得了不准确的结果。这是myfile.DAT:

# Time  forces(pressure, viscous) moment(pressure, viscous)
0.005   (((2 10 4) (3 6 0)) ((12 60 -13) (4.88 0.5 -0.32)))
0.01    (((2 20 2) (4 7 3)) ((0.0024 1 -70) (40 6000 -1200)))

这是C ++代码:

#include <iostream>
#include <fstream>
#include <string>

int main ()
{
  FILE * force;
  force = fopen("file.dat", "r");
  float timestep;
  float fxp;
  float fyp;
  float fzp;
  float fxv;
  float fyv;
  float fzv;
  float mxp;
  float myp;
  float mzp;
  float mxv;
  float myv;
  float mzv;

  char c;

  fseek(force,-285,SEEK_END);

  while(c != '\n')
  {
    c = fgetc(force);
  }

  fscanf(force, "%f    ((%f %f %f) (%f %f %f)) ((%f %f %f) (%f %f %f))", &timestep, &fxp, &fyp, &fzp, &fxv, &fyv, &fzv, &mxp, &myp, &mzp, &mxv, &myv, &mzv);

  fclose(force);

  float ftotal = fxp + fxv;

  std::cout << "Here is f_total = " << ftotal << " N" << std::endl;

  return 0;
}

结果如下:

Here is f_total = 0 N

显然这是错的。它必须是2 + 4 = 6.

2 个答案:

答案 0 :(得分:1)

您的fscanf格式字符串是:

"%f    ((%f %f %f) (%f %f %f)) ((%f %f %f) (%f %f %f))"

但应该是:

"%f    (((%f %f %f) (%f %f %f)) ((%f %f %f) (%f %f %f)))"

编辑:这很可能不是最好的方法(2回,1前进),但检查它是否适用于此更改:

fseek(force, -1, SEEK_END);

while (c != '\n')
{
    c = fgetc(force);
    fseek(force, -2, SEEK_CUR);
}

答案 1 :(得分:0)

1 fscanf返回扫描的字段数 - 所以快速检查是添加“int n = fscanf(....” - 然后检查“n”是你认为它应该是什么。这可以节省你很多人头疼。

2:优于假设从最后搜索的行长度,从文件的开头扫描\ n,然后在执行fscanf之前搜索到最后一次 - 这也可以让您轻松选择特定的行数。以下将扫描整个文件,然后回到最后一行(假设该文件没有\ n作为最后一个字符)

int lineno = 1;
int lastLine = 0;
while(c != EOF)
{
    c = fgetc(force);
    if(c == '\n')
    {
        ++lineno;
        lastLine = ftell(force);
    }
}
printf("%d lines, pos=%d\n", lineno, lastLine);
fseek(force, lastLine, SEEK_SET);