Регулировка формата в C - PullRequest
       27

Регулировка формата в C

0 голосов
/ 10 сентября 2018

Как, например, я хочу получить этот вывод

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%) и всегда будет делать 2 пробела между отрицательным знаком и цифрами (dis)?

Ответы [ 5 ]

0 голосов
/ 10 сентября 2018

Если вы хотите придерживаться семейства 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);
}

К сожалению, он использует промежуточный буфер. Если вы хотите этого избежать, я подозреваю, что вам лучше использовать собственный код форматирования для этого конкретного случая.

0 голосов
/ 10 сентября 2018

Вы можете сделать это, используя:

  • возврат 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%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
0 голосов
/ 10 сентября 2018

Если вы просто хотите иметь фиксированное количество пробелов между - и первой цифрой, просто выведите пробелы: "Discount(%2d%%) - %d\n"

Обратите внимание, однако, что это затруднит выравнивание слиния выше как ширина числа зависит от его величины.Чтобы добиться выравнивания с линией выше, вам нужно либо выбрать фиксированную ширину поля для номера скидки (и учесть дополнительные пробелы и сбои при игре больших чисел), либо вам необходимо рассчитать ширину второголиния первая, и добавьте первую строку соответственно.Последнее может быть достигнуто с помощью asprintf(), чтобы записать вторую строку во вновь выделенную строку, затем взять длину этой строки и соответствующим образом отформатировать первую строку.Последним шагом будет вывод строки для дословно второй строки.

0 голосов
/ 10 сентября 2018

Насколько я знаю, нет флага для добавления интервала между - и числом, но одним из решений может быть добавление дополнительного строкового буфера для записи желаемого формата:

#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;
}
0 голосов
/ 10 сентября 2018

Вы были довольно близко. Проблема заключалась в том, что если вы просто укажете ширину числа, по умолчанию оно будет по правому краю , поэтому номера разных размеров будут печататься в разных местах.

Примерно так должно быть ближе к тому, что вы ищете:

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