我遇到一个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创build的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);
这段代码不是我写的,而且工作了好几年。 然而,最近我们不得不重build/重新安装Windows NT 4.0操作系统和软件,现在我得到一个奇怪的错误。 程序使用顶部提供的代码读取txt文件,直到到达第123行,此时它读取第8列两次,导致所有后续variables被移动一个位置,彻底搞砸了最后一个该scheme的几行。 有趣的是,这个问题可以通过手工复制并粘贴第一批123行到一个新的txt文件,然后将最后几行逐一地粘贴到同一个新的txt文件中,并将其用作input(复制完成在写字板内的NT机器上)。 这样做消除了这个双重读取的问题。 我不知道什么问题会导致这个错误,但也让它被这样一个怪异/笨重的方法修复。 问题发生在新的和旧的input,所以我不认为input文件是问题,因为他们没有改变。
哦,此外,如果我更改txt文件中每列之间的空格数,错误的位置将改变。 将其减less到1空间会导致错误发生在120行左右,同时增加空格的数量(尝试7而不是5)将错误向下推到124行。
我不是编程专家(一直是一个学习 – 我需要的人),所以帮助搞清楚这一点将不胜感激。 谢谢!
候选人简化
没有找到问题的根源,但推荐这个来简化调试。 这将照顾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()
,通常用于二进制文件,在这里不需要恕我直言,是一个窗口的错误读取UNIX文本文件( \n
)在Windows打开在二进制模式"r"
和使用fscanf()
最好的阅读文本文件打开"rt"
。 没有发现指向第123行或其邻居作为问题领域。
麻烦您的fscanf()
指令。
推荐%lf
而不是%7lf
。
你的fprintf()
用"%7.3f"
输出至少 7个字符的浮点数,按照需要填充' '
。
您在fscanf()
后续使用"%7lf"
表示最多可以扫描7个字符。 所以当你printf / scanf 999.999一切正常,但是数字更大的时候,比如1000.007,你的扫描就是“1000.00”,而下一个"%7lf"
就是“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
之间添加空格不会改变功能。