minGW在fprintf与fscanf操作long double类型时偷的懒
前言
当年没少跳printf
和scanf
输出输入double
类型数据的坑。所以在研究c99标准的时候特别注意了关于fprintf
和fscanf
关于输出浮点型数的说明。
原来在使用printf
输出double的时候,转义字符应该为%f
或者%F
而在使用scanf
输出double的时候,转义字符应该为%lf
或者%lF
。
而更加气人的是,纠结了老半天该用大写F还是小写f,到最后却发现,人家只是在输出诸如nan/NAN, inf/INF
之类的字母的时候,指定大小写罢了(此处省略一万只草泥马)。
然鹅,解答了上述疑问之后,本着乐于探(zhe)索(teng)的精神,看了看fprintf
与fscanf
的其它定界符和修饰符。诶,这个修饰符看起来似乎眼熟…
fprintf
的L
修饰符
fscanf
的L
修饰符
long double
啊,记忆中从来没用过这么高精的浮点数。毕竟一般情况没必要,double
都显得太多,float
就足够了。
于是我试了一试long double
的格式输入输出,没想到捅出一个惊~天~大~秘~密~2333
那就是minGW在long double的处理上偷懒了,然鹅linux下的gcc毛事没有!看测试。
准备工作
环境
所使用的测试环境:免责声明做的倒还挺全,哼
- Windows-minGW64:
- WSL Ubuntu 18.04:
可以看到,Win下的minGW版本还领先linux自带的gcc一年。
测试代码
在Windows下和WSL下分别写了两个功能相同的demo。不用在意变量名了啦
- Windows:
type double.c
- linux:
喵 double.c
验证
编译阶段
为了更好地看到FSF的不负责任编译时期的错误信息,我们打开-Wall
,将显示所有警告信息。这次我们换个顺序,先试linux,再测试Win。
-
linux
可以看到,gcc默默地完工,没给出任何警告,一切都是那么的和谐。常言道:No news is good news. -
Windows
Excuse me喵喵喵?老哥你怎么了?警告咋恁多?
仔细研读警告信息,发现就一个事情,嚷嚷了八遍。顺带吐槽一下gcc的错误提示是真的长
minGW-gcc: f前面接L?自从我在Windows上出生,就没见过这玩意。
总而言之,就两个字:不认%Lf
!
运行
不认就不认呗,反正过编了。俗话说的好:码不在多,过编就行
来康康我们的运行结果。
- linux
不错,您的输出完美地解决了我的问题! - Windows
额。。警告没好货,果然翻车了。。
失败的解决方案:花式换格式字符
换了包括但不仅限于如下格式字符:
%lf, %llf, %lF, %llF, %LF
,无一不翻车。
好吧,老实一点,double
真香。
延伸探究:输入的数据去哪了?
那么使用%Lf
输入的数据去哪