fopen — fseek и fscan дают неверные результаты из файла .DAT в переполнении стека

У меня есть файл .dat, который постоянно обновляется. Я хочу получить данные из последней строки в файле. Но я получаю неточные результаты. Вот мой файл. 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.

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

Другие решения

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);
0

По вопросам рекламы [email protected]