我目前正在将一个C项目从linux移植到Windows,在此期间我遇到了一个奇怪的错误。在源文件中,它有以下两行:
fprintf(fp, "%4d %11.6f %11.6f %11.6f\n", cell->total_atom_no, 0, 0, 0);
printf("%4d %11.6f %11.6f %11.6f\n", cell->total_atom_no, 0, 0, 0);
要清楚,文件以二进制模式“wb”打开。 文件中的输出是:
18 0.000000 0.000000 166818935138251830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
虽然命令行中的输出是:
18 0.000000 0.000000 0.000000
命令行版本是正确的。 但是在linux下,文件和命令行都会给出正确的输出。我无法制作可重现的代码,就像我尝试一个简单的代码一样:
int a = 18;
fprintf(fp, "%4d %11.6f %11.6f %11.6f\n", a, 0, 0, 0);
它会给出预期的输出。我也不能上传原始文件,因为它长达数千行。但它通过编译没有错误,顺便说一句。
此时我真的很困惑,打印0怎么会导致错误?任何有关错误来源的提示都将不胜感激。
更新1 :
问题似乎与Gtk库有关。该程序有两个版本,一个命令行,另一个GUI用Gtk + 2编程。两个版本都使用包含上述代码的同一文件,但只有GUI版本才会出现此错误。
然后它似乎是一个与Gtk库有关的问题,但我不知道调试更进一步。
更新2 :
我尝试了以下两个修复
fprintf(fp, "%4d %11.6f %11.6f %11.6f\n", cell->total_atom_no, 0, 0, 0.0);
fprintf(fp, "%4d %11.6f %11.6f %11.6f\n", cell->total_atom_no, 0, 0, (float)0);
错误仍然存在。 我可以毫无问题地将这些零作为srings打印出来,但我需要知道出了什么问题。
答案 0 :(得分:1)
您对printf
的来电导致undefined behavior。原因是printf
和系列期望double
格式的"%f"
参数。您改为给它三个int
值。
由于int
(通常在现代平台上)32位而double
是64位,printf
将超出提供给函数的实际数据,并获取看似随机的数据从堆栈可能超出其限制。