首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >snprintf/sprintf是否覆盖倒数第二个参数的终止-null,就像strcat一样?

snprintf/sprintf是否覆盖倒数第二个参数的终止-null,就像strcat一样?
EN

Stack Overflow用户
提问于 2020-09-08 15:06:49
回答 2查看 1.3K关注 0票数 0

它显然是为strcat编写的,例如这里这里,以防,

代码语言:javascript
复制
char *strcat(char *s1, const char *s2);

然后,

s2的初始字符覆盖s1末尾的空字符。

但显然我在这里搜索了一下“C中连接字符串/文本”,我偶然发现了,它指出,

避免在C代码中使用strcat。最干净、也是最安全的方法是使用snprintf:

那么,对于snprintf/sprintf,下一个参数的第一个字符覆盖前一个参数的空终止是否也是一样的呢?我在文档中看不到这样的引用。

经验证据似乎表明,strcat和snprintf的行为方式是相同的。还是我的假设错了?

代码语言:javascript
复制
#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):3份(CatResult):4份 结果:abc strlen(snprintfResult):3份大小(SnprintfResult):4

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-08 15:13:33

您不能那样使用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之后写过,但是最终的效果更像我们回答是的话,因为这两个代码片段都做了相同的事情。

票数 0
EN

Stack Overflow用户

发布于 2020-09-08 15:09:21

snprintfsprintf不像strcat那样附加到先前的字符串。他们开始在传递给他们的缓冲区的开头写东西。

当在一个调用中写入多个字符串时,就像使用格式字符串"%s%s%s"一样,它们将连续地写入字符串,在它们之间没有空字符,并以空字符结尾。

如果希望它们附加到名为buffer的缓冲区中的现有字符串,则确定字符串的长度,例如n,并将buffer + n作为第一个参数而不是buffer传递。(对于snprintf,请注意,还应该从第二个参数中减去n,后者指定缓冲区中可用的字节数。)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63796696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档