问题描述
显然是为strcat
写的,例如here和here,以防万一,
char *strcat(char *s1,const char *s2);
然后
s2的起始字符覆盖s1末尾的空字符。
但是显然在这里搜索了“用C连接字符串/文字”,我偶然发现this,它指出,
那么snprintf/sprintf
的下一个参数的第一个字符会覆盖前一个参数的空终止符吗?在documentation中看不到这样的引用。
经验证据似乎表明,strcat和snprintf的行为相同。还是我的假设错了?
#include <string.h>
#include <stdio.h>
int main(int argc,char const *argv[])
{
printf( "Test Program Started\n");
const char* first = "a";
const char* second = "b";
const char* third = "c";
const int merged_length = (strlen(first) + strlen(second) + strlen(third) + 1); // +1 for null-termination
char* catResult;
catResult = malloc( merged_length * sizeof(char));
strcpy(catResult,first);
strcat(catResult,second);
strcat(catResult,third);
catResult[merged_length] = '\0';
printf("catResult:%s \tstrlen(catResult):%d \t sizeof(catResult):%d\n",catResult,strlen(catResult),sizeof(catResult));
free(catResult);
char* snprintfResult;
snprintfResult = malloc( merged_length * sizeof(char));
snprintf(snprintfResult,merged_length,"%s%s%s",first,second,third);
// catResult[merged_length] = '\0'; // not necessary as per documentation
printf("snprintfResult:%s \tstrlen(snprintfResult):%d \tsizeof(snprintfResult):%d\n",snprintfResult,strlen(snprintfResult),sizeof(snprintfResult));
free(snprintfResult);
}
测试程序已启动
catResult:abc strlen(catResult):3 sizeof(catResult):4
snprintfResult:abc strlen(snprintfResult):3 sizeof(snprintfResult):4
解决方法
snprintf
和sprintf
不会像strcat
那样附加到先前的字符串。他们从传递给他们的缓冲区的开头开始写。
当在单个调用中写入多个字符串时,如格式字符串"%s%s%s"
一样,它们将连续写入字符串,它们之间没有空字符,并以空字符结尾。
如果您希望它们追加到名为buffer
的缓冲区中的现有字符串,则确定字符串的长度,例如n
,然后将buffer + n
作为第一个参数传递buffer
中的。 (对于snprintf
,请注意,也应从第二个参数中减去n
,该参数指定缓冲区中有多少字节可用。)
您不能像这样使用sizeof
。尽管sizeof("string")
可以按预期工作,但sizeof(string pointer)
总是在任何给定平台上返回相同的值(通常为4或8)。
const int merged_length = (sizeof(first) + sizeof(second) + sizeof(third) + 1);
应该是
const int merged_length = (strlen(first) + strlen(second) + strlen(third) + 1);
当您将%s
写入snprintf
时,它会将字符串复制到目标字符串,而没有任何结尾的null。当到达格式字符串末尾的空终止符时,输出字符串也将以空终止。
因此,您的问题的实际答案是“否”,因为空值从未在first
之后写入,但是最终效果更像是如果我们回答“是”,因为这两个代码片段都做同样的事情。 / p>