C 语言中的格式调整



例如,我想有这个输出

Subtotal           20
Discount(10%)    -  2   //negative sign always have 2 spaces out from '2'

我试着像这样编码。

dis = subtotal*discount/100; //dis = 20*10/100
printf("Subtotal%13dn",subtotal);
printf("Discount(%d%s)%4s-%3dn",discount,"%"," ",dis);

但是如果没有折扣怎么办,我的输出会变成这样

数字向前移动到左侧

Subtotal           20
Discount(0%)    -  0

另外,如果我的小计和折扣非常大。

负号和数字粘在一起

Subtotal         1000
Discount(50%)    -500

如何编码,直到我的号码永远不会在折扣 (0%-100%( 之间向前移动到左侧或右侧,并且始终在负号和数字 (dis( 之间留出 2 个空格?

据我所知,没有标志可以在-和数字之间添加间距,但一种解决方案可能是添加一个额外的字符串缓冲区来写出所需的格式:

#include <stdio.h>
int main()
{
char discount_amount_string[255];
char discount_percent_string[255];
int subtotal = 2000;
int discount_percent = 10;
int discount_amount = subtotal * discount_percent / 100;
snprintf(discount_amount_string, sizeof(discount_amount_string), "-  %d", discount_amount);
snprintf(discount_percent_string, sizeof(discount_percent_string), "(%d%%)", discount_percent);
printf("Subtotal%15dn",subtotal);
printf("Discount%-7s%8sn", discount_percent_string, discount_amount_string);
return 0;
}

你可以这样做,使用:

  • printf的回归,告诉你字符是如何打印的
  • 可用于知道整数中字符数的log10函数:

代码可能如下所示:

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* get number of character in a number (when printed)*/
int int_print_size(int number)
{
if (number < 1) 
return 1;
else 
return 1+log10(number);
}

void print(int subtotal, int discount)
{
char spaces[] = "             ";
int dis = subtotal*discount/100; //dis = 20*10/100
int ref, len[2];
/* take size of first line as reference */
ref = printf("Subtotal%13dn",subtotal);
/* take the size of first part */
len[0] = printf("Discount(%d%%)",discount);
/* compute the printed size of `dis` */
len[1] = int_print_size(dis);
/* pad with characters from `spaces` array */
printf("%.*s-  %dnn", ref-4-len[0]-len[1], spaces, dis);           
} 
int main(int argc, char *argv[]){       
/* tests case */
print(20, 0);
print(20, 10);
print(100, 9);
print(100, 10);
print(100, 11);
print(1000, 50);
print(100000, 99);
return 0;
}

结果:

Subtotal           20
Discount(0%)     -  0
Subtotal           20
Discount(10%)    -  2
Subtotal          100
Discount(9%)     -  9
Subtotal          100
Discount(10%)   -  10
Subtotal          100
Discount(11%)   -  11
Subtotal         1000
Discount(50%)  -  500
Subtotal       100000
Discount(99%)-  99000

你很接近。问题是,如果你只指定数字的宽度,默认情况下它将是正确的对齐,这就是为什么不同大小的数字将打印在不同的地方。

像这样的东西应该更接近你正在寻找的东西:

printf("Discount(%d%%)    -  %dn",discount,dis);

如果您只想在-和第一个数字之间有固定数量的空格,只需输出空格:"Discount(%2d%%) - %dn"

但是请注意,这将很难与上面的行对齐,因为数字的宽度取决于其大小。要实现与上述行的对齐,您要么需要为折扣号码使用固定的字段宽度(并保留额外的空格,以及大数字运行时的失败(,要么需要先计算第二行的宽度,并相应地填充第一行。后者可以通过使用asprintf()将第二行写入新分配的字符串,然后获取该字符串的长度并相应地格式化第一行来实现。最后一步是逐字输出第二行的字符串。

如果你想坚持printf家族,你可以做这样的事情:

void print(int subtotal, int discount, int dis) {
char buf[255] = { 0 };
sprintf(buf, "Discount(%d%%)", discount);
printf("%-21s   %4dn", "Subtotal", subtotal);
printf("%-21s-  %4dn", buf, dis);
}

不幸的是,它使用中间缓冲区。如果你想避免这种情况,我怀疑你最好为这种特定情况滚动自己的格式化代码。

最新更新