Есть ли альтернатива setfill () для C? - PullRequest
4 голосов
/ 06 октября 2010

В C ++:

int main()
{
    cout << setfill('#') << setw(10) << 5 << endl;

    return 0;
}

Выходы:

#########5

Есть ли альтернатива setfill() для C? Или как сделать это в C без создания строки вручную?

Ответы [ 5 ]

5 голосов
/ 06 октября 2010
 int x= 5; 
 printf("%010d",x);

выведет: 0000000005

Теперь, если вы действительно хотите «#» вместо «0», вам придется заменить их вручную в строке.

Возможно:

char buf[11], *sp = buf; 
snprintf(buf, 11, "%10d", x); 
while( (sp = strchr(sp, ' ')) != '\0'){ *sp = '#'; }
puts(buf); 
3 голосов
/ 06 октября 2010

Нет, прямой альтернативы нет.

Но если у вас хорошо ведет себя snprintf (тот, который ведет себя, как описано в Стандарте C99), это работает без создания новой строки;создание только 2 временных int s

#include <stdio.h>

int main(void) {
  int filler = '#'; /* setfill('#') */
  int width = 10;   /* setw(10)     */
  int target = 5;   /* 5            */

  /* ******** */
  int s = snprintf(NULL, 0, "%d", target);
  for (int i = 0; i < width - s; i++) {
    putchar(filler);
  }
  printf("%d\n", target);
  /* ******** */

  return 0;
}

EDIT: рабочая версия на ideone .


EDIT2: различия между стандартом C99 snprintf и Windows _snprintf ( спасибо за ссылку, Бен ):

  • Прототип: int snprintf(char *restrict buffer, size_t n, const char *restrict format, ...);
  • Прототип: int _snprintf(char *buffer, size_t n, const char *format, ...);
  • snprintf записывает не более (n-1) байтов, а NUL
  • _snprintf записывает не более (n) байтов, последний из которых может быть NUL или другим символом
  • snprintf возвращает количество символов, необходимое для формата (может быть больше n) или -1 в случае ошибки кодирования
  • _snprintf возвращает отрицательное значение, если nне большой для строки;или n, если байт NUL не был записан в буфер.

Вы можете запустить неправильное поведение _snprintf в цикле, увеличивая n, пока не найдете правильное значение

/* absolutely not tested, written directly on SO text editor */
int i;
size_t rightvalue = 0;
char buffer[SOME_DEFAULT_VALUE];
do {
    if (sizeof buffer < rightvalue) /* OOPS, BIG BIG OOPS */;
    i = _snprintf(buffer, rightvalue, "%d", 42);
} while (i != rightvalue++);
/* rightvalue already has space for the terminating NUL */
2 голосов
/ 06 октября 2010

Каждый хочет позвонить printf дважды ... printf - одна из самых дорогих функций.

Здесь:

char buffer[18] = "##########";
puts(buffer + snprintf(buffer+strlen(buffer), 8, "%d", 5));
1 голос
/ 06 октября 2010

Не встроено как стандартное

Я бы, вероятно, использовал бы sprintf () число в строке и получил бы количество символов, а затем сначала вывел бы правильное число '#' перед печатью строки.

0 голосов
/ 06 октября 2010

Следующее будет делать это, используя memset в C, предполагая 1-байтовый символ. Он по-прежнему создает «строку», хотя я не уверен, насколько вручную вы этого не хотите.

int main(void)
{

   char buf[MAX_LENGTH];

   memset(buf, '#', 10);
   buf[10]='\0';
   printf("%s5\n", buf);
}

В зависимости от того, что вы на самом деле хотите с ним сделать, вы можете динамически создать буфер соответствующего размера и вернуть его из вспомогательной функции, если вы того пожелаете.

...