在我的代码中,我使用如下的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的source和destinaton是否相同,它会清除缓冲区。我希望输出是20s格式说明符。我不能在第一步中执行此操作,因为我需要附加多个字符串并在最后一步执行格式说明符。
复制到临时缓冲区并从那里复制到原始缓冲区唯一可能的解决方案?你能否对此有所了解。
答案 0 :(得分:7)
来自snprintf
man page
C99和POSIX.1-2001指定在调用时结果未定义 到sprintf(),snprintf(),vsprintf()或vsnprintf()会导致 复制发生在重叠的对象之间(例如,如果 目标字符串数组和提供的输入参数之一引用 相同的缓冲区。)
这意味着该行
snprintf(text, "%20s", text)
无效。您建议使用额外的临时缓冲区是正确的。
答案 1 :(得分: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的病态情况。