【发布时间】:2020-09-08 15:06:49
【问题描述】:
显然是写给strcat,例如here 和 here 以防万一,
char *strcat(char *s1, const char *s2);
那么,
s2 的起始字符覆盖 s1 末尾的空字符。
但显然在这里搜索“在 C 中连接字符串/文字”时,我偶然发现了 this,其中指出,
避免在 C 代码中使用 strcat。最干净,最重要的是,最安全的方法是使用 snprintf:
那么,对于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
【问题讨论】:
-
@user694733,哎呀!我的错!我会编辑和更正它。一秒钟。
-
@user694733,在我使用的 PC 上的原始测试代码中,我使用了
strlen。然后我想用sizeof测试并忘记在粘贴之前撤消该更改。现在好点了吗? -
snprintf(类似于strcat)的错误用法是snprintf(buf, buflen, "%s%s", buf, more_stuff);。这将适用于某些 C 库实现而不适用于其他库实现,但根据标准,它是未定义的行为。 -
@rici,好的。我明白。正如您在评论中的 sn-p 中显示的那样,源和目标不能重叠。
标签: c concatenation null-terminated