snprintf格式说明符

时间:2013-08-28 16:23:13

标签: c string printf

在我的代码中,我使用如下的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格式说明符。我不能在第一步中执行此操作,因为我需要附加多个字符串并在最后一步执行格式说明符。

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

2 个答案:

答案 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的病态情况。