fscanf double在文件中间读取变量 - Windows NT 4.0 dll

时间:2013-07-19 18:30:57

标签: c++ c windows scanf windows-nt

我遇到了在Windows NT 4.0 dll文件中读取txt文件的问题;在你问之前,我目前没兴趣将其迁移到新的操作系统。我只是想解决这个问题,并让其他人担心迁移这个超级遗留软件。

当我使用fscanf读取txt文件时出现问题,如图所示:

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

使用MATLAB创建的txt文件由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行批量复制并粘贴到新的txt文件,然后将最后几行逐个粘贴到同一个新的txt文件中并将其作为输入(复制完成)来解决。在写字板内的NT机器上)。这样做可以消除这种双读问题。我不知道哪些问题可以导致这个错误,但也让它由这种奇怪/笨重的方法修复。新输入和旧输入都会出现问题,所以我认为输入文件不是问题,因为它们没有改变。

哦,另外,如果我更改txt文件中每列之间的空格数,则错误的位置会发生变化。将其减少到1个空间会导致错误发生在120行左右,而增加空格数(尝试7而不是5)会将错误推到第124行。

我不是编程专家(一直是我需要学习的人),所以非常感谢帮助解决这个问题。谢谢!

2 个答案:

答案 0 :(得分:1)

您的fscanf()指令有问题。
建议%lf代替%7lf

fprintf() "%7.3f"使用至少 7个字符打印浮点数,并根据需要使用' '填充。

您在"%7lf"中随后使用fscanf()表示要扫描大多数 7个字符。因此,当你printf / 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 :(得分:0)

候选人简化

没有找到问题的 来源,但建议这样做以简化调试。这样可以处理PC行结尾,过度操作文件指针,%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(),通常用于二进制文件,这里不需要恕我直言,是一个Window的错误,读取在Windows中以二进制文件打开的UNIX文本文件(\n)模式"r"并使用fscanf()最佳阅读文本文件"rt"。没有发现任何东西指向第123行或其邻居作为问题区域。