【发布时间】:2011-04-21 12:35:36
【问题描述】:
在 C++ 中:
int main()
{
cout << setfill('#') << setw(10) << 5 << endl;
return 0;
}
输出:
#########5
C 是否有任何setfill() 替代方案?或者如何在不手动创建字符串的情况下在 C 中做到这一点?
【问题讨论】:
标签: c++ c output-formatting
在 C++ 中:
int main()
{
cout << setfill('#') << setw(10) << 5 << endl;
return 0;
}
输出:
#########5
C 是否有任何setfill() 替代方案?或者如何在不手动创建字符串的情况下在 C 中做到这一点?
【问题讨论】:
标签: c++ c output-formatting
不作为标准内置
我可能会将数字 sprintf() 转换为字符串并获取字符数,然后在打印字符串之前首先输出正确的“#”数。
【讨论】:
下面将使用 C 中的 memset 来执行此操作,假设为 1 字节字符。它仍然会创建一个“字符串”,但我不确定您不希望它是多么手动。
int main(void)
{
char buf[MAX_LENGTH];
memset(buf, '#', 10);
buf[10]='\0';
printf("%s5\n", buf);
}
根据您实际想用它做什么,您可以动态地创建适当大小的缓冲区,并根据需要从辅助函数中返回它。
【讨论】:
sizeof (char) == 1。该标准将其定义为这样。 (可能会改变的是位数,请参阅 CHAR_BIT。)
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("%s", buf); 或者更好的是,使用puts。
不,没有直接的选择。
但是,如果您有一个行为良好的snprintf(其行为符合 C99 标准的描述),则无需创建新字符串即可工作;仅创建 2 个临时 ints
#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;
}
编辑:在ideone 运行版本。
EDIT2:C99 标准的 snprintf 和 Windows _snprintf 之间的差异(谢谢你的链接,Ben):
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 以防编码错误n 对于字符串来说不大,_snprintf 返回负值;或 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 */
【讨论】:
snprintf() 在 VS2008 中找不到。 snprintf 有什么问题?
_snprintf,此处描述:msdn.microsoft.com/en-us/library/2ts7cx93.aspx
每个人都想调用printf 两次...printf 是最昂贵的函数之一。
这里:
char buffer[18] = "##########";
puts(buffer + snprintf(buffer+strlen(buffer), 8, "%d", 5));
【讨论】: