2

在我的代码中,我使用如下 snprintf 并且可以看到以下行为

char text[30] = {0};

snprintf(text, sizeof(text), "%s", "hello");
printf("Interm... %s\n", text);
snprintf(text, "%20s", text);
printf("At the end ... %s\n", text);

输出

Interm... hello
At the end ... 

如您所见,如果 snprintf 的源和目标相同,它会清除缓冲区。我希望输出采用 20 年代的格式说明符。我不能在第一步中执行此操作,因为我需要附加多个字符串并在最后一步执行格式说明符。

复制到临时缓冲区并从那里复制到原始缓冲区是唯一可能的解决方案吗?您能否对此有所了解。

4

2 回答 2

5

snprintf 手册页

C99 和 POSIX.1-2001 指定如果调用 sprintf()、snprintf()、vsprintf() 或 vsnprintf() 会导致在重叠的对象之间发生复制(例如,如果目标字符串数组和提供的输入参数之一引用相同的缓冲区)。

这意味着该行

snprintf(text, "%20s", text)

无效。您关于使用额外的临时缓冲区的建议是正确的。

于 2013-08-28T16:26:02.290 回答
0

为了实现您的目标:str1 后跟 str2,所有这些在左侧用空格填充,或在右侧截断,长度为 (wid) 个字符,存储在 outbuf 中(必须至少为 wid+1 个字符宽) 你可以只使用一个 sprintf...

size_t len1=strlen(str1), len2=strlen(str2);
if (len2 > wid-len1) { len2 = wid-len1; }
snprinf(outbuf, wid+1, "%*s%.%s", wid-len2, str1, len2, str2);

请注意, (wid-len2) 是 str1 在输出上的填充大小, len2 是 str2 在输出上的截断大小。snprintf() 中的 wid+1 缓冲区大小是对 len1>wid 的病态情况的防范。

于 2013-08-28T18:04:47.093 回答