首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么当我们使用相同的源和目的地时,sprintf和snprintf的行为是不同的?

为什么当我们使用相同的源和目的地时,sprintf和snprintf的行为是不同的?
EN

Stack Overflow用户
提问于 2013-10-21 09:00:22
回答 3查看 4.8K关注 0票数 4

我有一个使用sprintf的简单代码

代码语言:javascript
运行
复制
    #include <stdio.h>

    int main()
    {

            char str_src [1024]={"Hello"};
            sprintf(str_src,"%s%s",str_src,"hiiiiiiiiiii");
            printf("result = %s",str_src);  

    }

当我编译时,我得到了正确的结果:

结果= Hellohiiiiiiiiiii

但由于sprintf不安全,我决定将其改为snprintf。我以为这会很简单。我将sprintf改为snprintf,如下所示

代码语言:javascript
运行
复制
snprintf(str_src,1024,"%s%s",str_src,"hiiiiiiiiiii");

现在,如果编译并运行代码,就会得到不同的结果。

结果= hiiiiiiiiiii

如果我使用str_src作为第四个参数(作为%s的值),我将面临这个问题。为什么snprintf的行为与sprintf不同?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-10-21 09:04:22

使用与目标和源相同的缓冲区是未定义的行为。

来自C11规范(7.21.6.6/2):

如果复制发生在重叠的对象之间,则行为是未定义的。

snprintf (7.21.6.5/2)也是如此,va_list变体也是如此。

不幸的是,这在运行代码中是很常见的,但是不能真正依靠它来工作。

票数 14
EN

Stack Overflow用户

发布于 2013-10-21 09:04:57

来自sprintf手册:

C99和POSIX1.2001指定,如果调用sprintf()、snprintf()、vsprintf()或vsnprintf()将导致重叠的对象之间进行复制(例如,如果目标字符串数组和提供的输入参数之一引用同一个缓冲区),则结果是未定义的。见注。

这个问题没有答案,因为您的代码有未定义的行为。

票数 5
EN

Stack Overflow用户

发布于 2013-10-21 09:05:02

不,在这两种情况下都会得到完全任意的结果,因为这是未定义的行为。其中一个恰好是你想要的。在不同的计算机上你可能得到不同的结果。不管它的价值是什么,它可能会格式化您的硬盘驱动器,但仍然是正确的行为。只是不要使用重叠的源和目标。

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

https://stackoverflow.com/questions/19490134

复制
相关文章

相似问题

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