如何使用printf()格式化字符串以获得相等长度的输出

122

我有两个函数,一个会输出像是Starting initialization...这样的信息,另一个会检查返回码并输出"Ok""Warning""Error"。但是产生的输出长度不同:

Starting initialization...Ok.
Checking init scripts...Ok.

我该如何获得以下类似的东西?

Starting initialization...       Ok.
Checking init scripts...         Ok.
6个回答

202

您可以在字符串字段上指定宽度,例如:

printf("%-20s", "initialization...");

然后使用该字段打印的任何内容都将被填充为空白,直到达到指定的宽度。

- 左对齐该字段中的文本。


133
唉,我不够聪明以至于无法数到那么高。但是,我相信提问者足够聪明,可以从我的例子中推断出来 :) - Carl Smotricz
4
右对齐呢?K&R中没有提到任何标志。 - Ungeheuer
12
默认情况下,数据将向右对齐。如果没有使用“-”符号,您的数据将在您指定宽度的字段中右对齐。 - Carl Smotricz

33

此外,如果您希望灵活选择 width,可以在以下两种格式中选择其中之一(带截断或不带截断):

int width = 30;
// No truncation uses %-*s
printf( "%-*s %s\n", width, "Starting initialization...", "Ok." );
// Output is "Starting initialization...     Ok."

// Truncated to the specified width uses %-.*s
printf( "%-.*s %s\n", width, "Starting initialization...", "Ok." );
// Output is "Starting initialization... Ok."

30

printf 允许使用宽度说明符格式化输出。例如:

printf( "%-30s %s\n", "Starting initialization...", "Ok." );

使用负的宽度说明符来指示左对齐,因为默认情况下会使用右对齐。


16

另外还有一个%n修饰符,它可以在特定情况下帮助。它返回字符串已经输出的列数。例如:您想要编写几行文本,这些文本在第一行的宽度内就像一个表格一样。

int width1, width2;
int values[6][2];
printf("|%s%n|%s%n|\n", header1, &width1, header2, &width2);

for(i=0; i<6; i++)
   printf("|%*d|%*d|\n", width1, values[i][0], width2, values[i][1]);

将打印两列,这两列的宽度都与字符串header1header2的长度相同。我不确定所有实现都有%n,但Solaris和Linux都有。


1
这个解决方案是可行的,但任何将其放入他们的代码中的人都应该意识到引入内存漏洞的风险。 - Matthew Cole

1

还有一种相对低技术的解决方案,即通过手动计算添加空格来使您的消息排列整齐。您可以在消息字符串中包含一些尾随空格。


-2

从使用制表符开始 - 使用\t字符修改器。它将前进到固定位置(列,终端术语)。

然而,如果超过列宽(如果我没记错,是4个字符),它就无法帮助了。

为了解决这个问题,使用固定数量的制表符(5?6?试试)编写您的“OK/NOK”内容。然后返回(\r)而不是换行,并编写您的消息。


8
字符串过长可能会超出制表符的位置,导致制表符和文本错位。 - PP.
1
不完全是这样...首先写带有选项的OK/NOK,然后加上/r,接着写短语,最后加上/n。这样短语可以覆盖掉OK/NOK。 但是你的方法更好,我之前不知道还有负对齐的功能。 - jpinto3912

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