25

我正在开发适用于各种 Unix 和 Windows 32 位和 64 位操作系统的应用程序。

我正在使用long double数据类型,当我这样做sprintf()并在其中使用long double%lf ,它可以在 Windows 上正常工作,不会出现任何错误,但是在 Solaris 平台上它会提供核心转储。

相同问题的示例代码如下。

void main(){
    string size = "16622";
    string sizeFact = "20";
    long long sizeLongLong = strtoll(size);
    int factInt = atoi(sizeFact);
    long double sizeLongDouble = (long double) sizeLongLong/pow(2, factInt);
    char buf[512];
    sprintf(buf, "%.3lf %s", sizeLongDouble, "str");    
}

如上所述,代码在 Windows 32 位和 64 位上运行良好,但是对于 sprintf,它为我提供了 Solaris 上的核心。

我尝试在 sprintf 中进行类型转换,效果很好。

sprintf(buf, "%.3lf %s", (double) sizeLongDouble, "str");

格式说明符有什么用long double

我在这里犯了什么错误,我是否使用了错误的格式说明符,因为它提供了核心?

为什么我需要在 sprintf() 中再输入一次 cast?

4

4 回答 4

25

因为long double你应该使用 format "%Lf"。使用小 L(即"%lf")进行格式化对 POSIX 系统没有影响(请参阅规范)。

于 2013-02-14T09:27:23.697 回答
3

文档清楚地说明了这一点:

大号

a 、A、e、E、f、F、gG转换后的 A 对应于 long double 参数。(C99 > 允许 %LF,但 SUSv2 不允许。)

所以,你应该使用%Lf.

于 2013-02-14T09:29:14.413 回答
1

我会将此添加为评论,但我还不能这样做。同样重要的是要注意,您也可以通过long double这种方式使用指数“p”表示法:

  • 定点符号:%Lf
  • 指数符号:%Le
  • p 符号:%La
于 2015-08-15T21:22:30.483 回答
0

取决于我见过的编译器%Lf%llf尝试两者,看看哪个有效。%lf您使用的是 not for 的格式说明doublelong double。我相信g++你应该使用%llf,而在视觉工作室它是%Lf

于 2013-02-14T09:25:10.030 回答