C++:为什么我不能用sprintf打印const char*?

War*_*tin 5 c++ string printf pointers const

我在这里错过了什么?这让我疯了!

我有一个返回const char*函数

const char* Notation() const
{
    char s[10];
    int x=5;
    sprintf(s, "%d", x);
    return s;
}
Run Code Online (Sandbox Code Playgroud)

现在在代码的另一部分我这样做:

.....
.....
char str[50];       
sprintf(str, "%s", Notation());
.....
.....
Run Code Online (Sandbox Code Playgroud)

但是str保持不变.

如果相反,我这样做:

.....
.....
char str[50];
str[0]=0;
strcat(str, Notation());
.....
.....
Run Code Online (Sandbox Code Playgroud)

str正确设置.

我想知道为什么sprintf不能按预期工作......

haw*_*awk 9

您正在尝试返回在堆栈上分配的数组,并且其行为未定义.

const char* Notation() const
{
    char s[10];
    int x=5;
    sprintf(s, "%d", x);
    return s;
}
Run Code Online (Sandbox Code Playgroud)

s从函数返回后,这里不会出现Notation().如果你不关心线程安全,你可以做s静态.

const char* Notation() const
{
    static char s[10];
    ....
Run Code Online (Sandbox Code Playgroud)

  • @Wartin - 粗略地说,函数内部的静态会将变量的生命周期延长到程序的末尾.但是可见性就像一个自动变量.它不是线程安全的原因很简单,多线程可以在函数中同时执行并相互踩踏. (2认同)

Naw*_*waz 5

在这两种情况下,它都会调用未定义的行为,因为Notation()返回一个在返回时被销毁的本地数组.你不幸的是它在一个案例中起作用,让你觉得它是正确的.

解决方案是std::string用作:

std::string Notation() const
{
    char s[10];
    int x=5;
    sprintf(s, "%d", x);
    return s; //it is okay now, s gets converted into std::string
}
Run Code Online (Sandbox Code Playgroud)

或者使用C++流作为:

std::string Notation() const
{
    int x=5;
    std::ostringstream oss;
    oss << x;
    return oss.str(); 
}
Run Code Online (Sandbox Code Playgroud)

然后:

char str[50];       
sprintf(str, "%s", Notation().c_str());
Run Code Online (Sandbox Code Playgroud)

的好处(美容)std::ostringstream(和std::string)就是你不必知道输出提前的大小,这意味着你不必使用幻数,如10在数组声明char s[10].从这个意义上说,这些类是安全的.