fscanf двойное чтение переменной в середине файла — Windows NT 4.0 dll

У меня проблема с чтением TXT-файла в DLL-файле Windows NT 4.0; и, прежде чем вы спросите, я не заинтересован в переносе этого на новую ОС. Я просто хочу решить эту проблему и позволить другим после меня беспокоиться о переносе этого супер-унаследованного программного обеспечения.

Проблема возникает, когда я читаю текстовый файл с помощью fscanf, как показано:

infile_ptr = fopen("c:\\LumaGem\\orbit.txt", "r");
byteoffset=0;
while(!feof(infile_ptr) )
{
r=0.0; s1=0.0; s2=0.0; e1=0.0; e2=0.0; e3=0.0; d=0.0; f=0.0;
fseek(infile_ptr, byteoffset, SEEK_SET);
fscanf(infile_ptr,"%7lf %7lf %7lf %7lf %7lf %7lf %7lf %7lf", &r, &s1, &s2, &e1, &e2, &e3, &d, &f);

byteoffset=0; byteoffset = ftell(infile_ptr);
}
fclose(infile_ptr);

Файл txt, созданный с помощью MATLAB, состоит из 128 строк по 8 столбцов, разделенных 5 пробелами, и отформатирован так же, как и в MATLAB:

fprintf(fid,'%7.3f     %7.3f     %7.3f     %7.3f     %7.3f     %7.3f     %7.3f     %7.3f \n', variables);

Этот код не был написан мной, и работал в течение нескольких лет. Однако недавно нам пришлось перестраивать / переустанавливать ОС Windows NT 4.0 и программное обеспечение, и теперь я получаю странную ошибку. Программа прекрасно читает txt-файл, используя код, представленный сверху, пока не дойдет до строки 123, после чего дважды читает 8-й столбец, в результате чего все последующие переменные будут сдвинуты на одну позицию, полностью испортив последнюю несколько строчек программы. Интересно, что эту проблему можно решить, вручную скопировав и вставив первые 123 строки в новый текстовый файл, а затем последние несколько строк одну за другой в тот же новый текстовый файл и используя его в качестве входных данных (копирование выполнено на машине NT внутри компа). Это устраняет проблему двойного чтения. Я понятия не имею, какие проблемы могут вызвать эту ошибку, но также и позволить исправить ее таким странным / неуклюжим методом. Проблема возникает с новыми и старыми входами, поэтому я не думаю, что входные файлы являются проблемой, так как они не изменились.

Да, и дополнительно, если я изменю количество пробелов между каждым столбцом в текстовом файле, местоположение ошибки будет смещено. Уменьшение его до 1 пробела приводит к возникновению ошибки в строке 120 или около того, в то время как увеличение количества пробелов (пробовал 7 вместо 5) толкнул ошибку до строки 124.

Я не эксперт по программированию (я всегда учился так, как мне нужно), так что помощь в выяснении этого будет очень признательна. Спасибо!

2

Решение

Кандидатское упрощение

не нашел источник проблемы, но рекомендовал это, чтобы упростить отладку. Это заботится об окончаниях строк ПК, чрезмерных манипуляциях с указателем файла, ненужном ограничении %7lf и обеспечивает лучшую проверку ошибок.

FILE *infile_ptr = fopen("c:\\LumaGem\\orbit.txt", "rt");  // PC text file
char buf[1000];
while (fgets(buf, sizeof(buf), infile_ptr)) {  // separate I/O from scanning
int count = sscanf(buf,"%lf%lf%lf%lf%lf%lf%lf%lf", &r, &s1, &s2, &e1, &e2, &e3, &d, &f);
if (count != 8) { // check for correct scan count
; //handle error;
}
}
if (ferror(infile_ptr)) {
; //handle error;
}
fclose(infile_ptr);
[Редактировать] OP опубликовал оригинальный текстовый файл.

Также добавьте эту строку в цикл, чтобы позаботиться о конечных строках, состоящих только из пробелов.

  if (count <= 0) continue;
[Править] Заключение.

Использование fseek() а также ftell(), обычно используемый с бинарными файлами, здесь IMHO не нужен, это ошибка Window, читающая текстовый файл UNIX (\n) открывается в Windows в двоичном режиме "r" и используя fscanf() который работает лучше всего, чтение текстовых файлов открыть "rt", Ничего не найдено, чтобы указать на линию 123 или ее соседей в качестве проблемной области.

0

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

Беда с твоим fscanf() директивы.
Рекомендую %lf вместо %7lf,

Ваш fprintf() с "%7.3f" печатает числа с плавающей запятой, используя в наименее 7 символов для заполнения ' ' по мере необходимости.

Ваше последующее использование "%7lf" в fscanf() говорит сканировать на самый 7 символов. Поэтому, когда вы печатаете ff / scanf 999.999, все в порядке, но с большими числами, такими как 1000.007, ваше сканирование принимает значение «1000.00» и оставляет «7» для следующего "%7lf",

 int main(void) {
char buf[1000];
double f1, f2;
int r;
sprintf(buf, "%7.3f %7.3f", 1.23, 4.56);
r = sscanf(buf, "%7lf %7lf", &f1, &f2);
printf("'%s'\n%d %g %g\n", buf, r, f1, f2);

sprintf(buf, "%7.3f %7.3f", 999.999, 4.56);
r = sscanf(buf, "%7lf %7lf", &f1, &f2);
printf("'%s'\n%d %.10g %.10g\n", buf, r, f1, f2);

sprintf(buf, "%7.3f %7.3f", 1000.007, 4.56);
r = sscanf(buf, "%7lf %7lf", &f1, &f2);
printf("'%s'\n%d %.10g %.10g\n", buf, r, f1, f2);

return 0;
}

Output:
'  1.230   4.560'
2 1.23 4.56
'999.999   4.560'
2 999.999 4.56
'1000.007   4.560'
2 1000 7

Кстати: для fscanf(), "%lf%lf%lf ..." все в порядке. Добавление пробелов между %lf не меняет функциональность.

1

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