我有一个包含字符串和长度的结构体:
typedef struct string {
char* data;
size_t len;
} string_t;
这一切都很好,但是我想使用类似于
printf
的函数输出此结构体的内容。data
可能没有空终止符(或在错误位置),因此我不能仅使用%s
。但是,%.*s
格式说明符需要一个int
,而我有一个size_t
。
所以问题现在是,如何使用printf
输出字符串?
%.*s
格式说明符: 假定您的字符串不包含任何嵌入的NUL字符,在将转换为之后,您可以使用%.*s
格式说明符:
string_t *s = ...;
printf("The string is: %.*s\n", (int)s->len, s->data);
这也是假设您的字符串长度不超过 INT_MAX
。如果您的字符串长度超过 INT_MAX
,那么您会有其他问题(例如打印出 20 亿个字符需要相当长的时间)。
int
的嵌入式或历史设备。 - user4815162342size_t
呢?” - Jeremy Rodiint
而不是size_t
是因为它要向后兼容在C语言标准化之前编写的代码,甚至在size_t
类型出现之前。 - Adam Rosenfield一个简单的解决方案就是使用未格式化输出:
fwrite(x.data, 1, x.len, stdout);
for (size_t i, remaining = x.len;
remaining > 0 && (i = fwrite(x.data, 1, remaining, stdout)) > 0;
remaining -= i) {
}
x.len
不大于SIZE_T_MAX
。在使用fwrite
时要注意这一点。snprintf
的?你可以使用 memcpy
来写入内存位置,而不是文件... - Kerrek SBmemcpy
复制字符串,然后使用snprintf
在我想要的位置输出数字。我认为这不如一次性完成所有操作好... - Jeremy Rodi%.*s
格式化打印更可取。 - Kerrek SB如何使用printf输出字符串?
一次性输出? 由于您可能在奇怪的地方有空终止符号,因此无法以任何有意义的方式进行操作。 通常,如果您的缓冲区可能包含不可打印的字符,则需要在输出字符串时确定您希望如何打印(或不打印)这些字符。 编写循环,测试每个字符,并根据逻辑判断打印它(或不打印)。
size_t
的值在int
类型范围内,就可以将其转换为int
。 - Kerrek SBint
的范围,那么这将是一个有趣的printf
调用。应该检查一下,因为可能会溢出。 - cnicutar