Linux中的printf问题

4
以下是一个简单的程序,用于在HP和Linux上打印格式化的“1.2”。然而,它们的行为不同。 我不想让问题变得更大,但实际发生这种情况的程序中有一个字符串中的浮点值,因此不能使用%f选项(即使使用sprintf也不行)。
有人遇到过这种情况吗?哪种行为是正确的?
这不应该是编译器问题,但仍然尝试了gcc、icpc、icc和g++。
#include <stdio.h>

int main()
{
   printf("%s = [%010s]\n", "[%010s]",  "1.2");
   return 0;
}

**HP:**
cc test2.c -o t ; ./t
[%010s] = [00000001.2]

**Linux:**
icc test2.c -o t ; ./t
[%010s] = [       1.2]

编辑:非常感谢大家的回复 :)

4个回答

7

来自glibc的printf(3)手册:

   0      The value should be zero padded.  For d, i, o, u, x, X, a, A, e,
          E,  f, F, g, and G conversions, the converted value is padded on
          the left with zeros rather than blanks.  If the 0  and  -  flags
          both  appear,  the  0  flag is ignored.  If a precision is given
          with a numeric conversion (d, i, o, u, x, and X), the 0 flag  is
          ignored.  For other conversions, the behavior is undefined.

在基于glibc的系统上,使用s参数的0标志不能保证将字符串填充为0


3
关键在于该行为未定义,因此他在HPUX和Linux之间得到不同结果是可以理解的。 - Brian Roach
1
这是Linux移植项目的一部分。因此,固有要求是我们需要完全匹配HP所做的事情:( - Sudeep

2
根据man页面,对于除d、i、o、u、x、X、a、A、e、E、f、F、g和G转换以外的任何内容,0标志的行为未定义。所以两者都可以。
编辑:当我说“可以”时,我是指从编译器/ libc 的角度来看是可以的。从你的应用程序的角度来看,你依赖的行为(在Linux和HP上)是一个错误,你应该正确地进行格式化打印。

在我们的情况下,HP中的行为是参考。也许我可以探索使用sprintf将%f作为0填充字符串存储,然后使用printf的选项。 - Sudeep

1

如果您不想要前导零填充,请省略前导零填充指示符:

printf("%s = [%10s]\n", "[%010s]",  "1.2");

实现填充字符串为零有些令人惊讶,但很容易进行修正。


我需要前导0填充 :) - Sudeep

0

补充Ignacio Vazquez-Abrams所说,根据printf的文档,你所做的结果是未定义的行为。两个操作系统产生不同的结果并不意外。

事实上,在Ubuntu上使用gcc 4.5.2编译您的代码会出现以下警告:

警告:'0'标志与“%s”gnu_printf格式一起使用


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接