【问题标题】:Is this printf format possible (left-justify sign and no sign on zero)?这种 printf 格式是否可能(左对齐符号且零上没有符号)?
【发布时间】:2017-09-18 20:56:22
【问题描述】:

我正在尝试使用 printf 来获得以下编程输出:

- 20
- 15
- 10
-  5
   0
+  5
+ 10
+ 15
+ 20

关键规格是:

  • 字段宽度始终为 4
  • 符号总是左对齐
  • 数字始终右对齐
  • 零没有符号

到目前为止,我还没有想出一个 printf 语句来给我想要的结果。我最接近的是:

for(int i = -20; i <= 20; i+=5)
{
    printf("%-+4d \n", i);
}

产生:

-20
-15
-10
-5
+0
+5
+10
+15
+20

有没有办法做到这一点而不必进行任何繁琐的字符串操作?

【问题讨论】:

  • 如果i 超出范围 [-999... + 999],输出应该是什么?还是说“不在乎”?
  • 在此应用程序中,i 仅在 [-20, 20] 范围内。但是,对于可能查看此问题的其他人,注意 i 的有效范围对于有效答案很重要。

标签: c string formatting printf string-formatting


【解决方案1】:
printf("%c%3d\n", i>0 ? '+' : i<0 ? '-' : ' ', abs(i));

请注意,上述 INT_MIN 失败,但这不应该成为问题,因为您的值预计只会小于 1000。

【讨论】:

  • 该死的以 1 分钟的优势击败了我,并在一行中获得了它。 +1
  • @Tyler,好吧,由于您的回答,我发现了一个错误。 (我认为0 应该是+0。已修复。)
  • 糟糕,我没有运行你的。
  • i = INT_MIN; -> 繁荣。
  • @EOF,在答案中提到了限制。我也没有适用于INT_MIN 的便携式解决方案。切换到llabs(并调整格式说明符)应该可以解决问题,但似乎不能保证long long intint 长。
【解决方案2】:

一个简单的单行代码,与其他行没有太大区别,但可以很好地查找"- +" 字符串。

printf("%c%3d\n", "- +"[i >= 0 + i > 0], abs(i));

要处理 [-999 ... + 999] 范围之外的值,尤其是讨厌的 i = INT_MIN,其中 -i未定义的行为,代码可以使用:

printf("%c%3u\n", "- +"[i >= 0 + i > 0], (i < 0) ? 0u - i: 0u + i);
// or
printf("%c%3lld\n", "- +"[i >= 0 + i > 0], llabs(i));

对于迂腐的全方位解决方案

// Buffer size = iceil(bit-width * log2(10)) + sign + null character
#define INT_BUF_SIZE (CHAR_BIT * sizeof(int)*31/100 + 3)

int print_int(int x) {
  char buf[INT_BUF_SIZE*2];
  sprintf(buf, "%+d", x);
  int width = 4;
  return printf("%c%*s\n", x ? buf[0] : ' ', width - 1, buf + 1);
}

示例输出

- 20
   0
+ 20
+2147483647
-2147483648

【讨论】:

  • 请注意,虽然这很聪明,但现代 C++ 编译器倾向于在整数上下文中使用 bool 表达式时发出警告(这是公平的,因为这通常是一个错误)。禁用该警告所需的恶作剧(使用编译指示或通过添加强制转换来显示意图)使其不那么有吸引力。
  • @Miral 由于帖子和答案是 C 而不是 C++,您是否发现与 C 编译器相同的 issue?这里没有bool 表达式。 i &gt;= 0int 之一。
【解决方案3】:
for(int i = -20; i <= 20; i+=5) {
    if( i < 0 ) 
        printf("-%3d \n", -i);
    else if(i == 0)
        printf("  0 \n");
    else
        printf("+%3d \n", i);
}

【讨论】:

  • 您应该使用else 以避免不必要的检查。 /// abs(i) 可以简化为 -i。 /// printf(" %3d \n", i); 可以简化为 printf(" 0 \n");
【解决方案4】:
for(int i = -20; i <= 20; i += 5){
    if(i == 0){
        printf("%4d\n", i);
    }
    else{
        (i > 0) ? printf("+%3d\n", i) : printf("-%3d\n", -i);
    }
}

虽然很丑,但是很管用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多