Есть ли на SETFILL () альтернативы для C?
-
28-09-2019 - |
Вопрос
В C ++:
int main()
{
cout << setfill('#') << setw(10) << 5 << endl;
return 0;
}
Выходы:
#########5
Есть ли setfill()
Альтернатива для C? Или как сделать это в C, не вручную создавая строку?
Решение
Нет, нет прямой альтернативы.
Но если у вас есть хорошо себя snprintf
(тот, который ведет себя, как описано стандартом C99), это работает без создания новой строки; Создание только 2 временных int
с
#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;
}
Редактировать: запущенная версия на Идеон.
Редактировать2: различия между стандартом C99 snprintf
и окна _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) байты и нуль_snprintf
пишет не более (n) байты, последний из которых может быть нуль или другим характеромsnprintf
Возвращает количество символов, необходимых для формата (может быть большеn
) или-1
В случае ошибки кодирования_snprintf
Возвращает отрицательное значение, еслиn
не большой для строки; илиn
Если Nul Byte не был записан на буфер.
Вы можете запустить неправильное ведение _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 */
Другие советы
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);
Все хотят позвонить printf
дважды... printf
является одной из самых дорогих функций вокруг.
Здесь:
char buffer[18] = "##########";
puts(buffer + snprintf(buffer+strlen(buffer), 8, "%d", 5));
Не встроен как стандарт
Я бы, вероятно, SPRINTF () номер в строке и получите количество символов, а затем выведите правильное количество «#», прежде чем печатать строку.
Следующее сделает это, используя memset
в C, предполагая 1-байтовый чар. Это все еще создает «строку», хотя я не уверен, как вручную вы не хотите, чтобы это было.
int main(void)
{
char buf[MAX_LENGTH];
memset(buf, '#', 10);
buf[10]='\0';
printf("%s5\n", buf);
}
В зависимости от того, что вы хотите сделать с этим, вы можете динамически создавать буфер, чтобы быть соответствующим размером и возвращать его из функции помощника, если вы так желаете.