C中的格式调整

Format Adjustment in 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%13d\n",subtotal);
printf("Discount(%d%s)%4s-%3d\n",discount,"%"," ",dis);

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

数字向前移动到左侧

Subtotal           20
Discount(0%)    -  0

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

负号和数字粘在一起

Subtotal         1000
Discount(50%)    -500

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

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

像这样的东西应该更接近您要找的东西:

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

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

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

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

#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%15d\n",subtotal);
    printf("Discount%-7s%8s\n", discount_percent_string, discount_amount_string);

    return 0;
}

你可以这样做,使用:

  • printf 的 return 告诉你字符是如何打印的
  • 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%13d\n",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-  %d\n\n", 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 系列,您可以这样做:

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

不幸的是,它使用了一个中间缓冲区。如果您想避免这种情况,我怀疑您最好针对这种特定情况使用自己的格式化代码。