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不能按预期工作......
您正在尝试返回在堆栈上分配的数组,并且其行为未定义.
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)
在这两种情况下,它都会调用未定义的行为,因为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].从这个意义上说,这些类是安全的.