[英]C++ : Why I can't print a const char* with sprintf?
What am I missing here ? 我在这里错过了什么? It's driving me nuts ! 这让我疯了!
I have a function that returns a const char* 我有一个返回const char *的函数
const char* Notation() const
{
char s[10];
int x=5;
sprintf(s, "%d", x);
return s;
}
Now in another part of the code I am doing this : 现在在代码的另一部分我这样做:
.....
.....
char str[50];
sprintf(str, "%s", Notation());
.....
.....
but str remains unchanged. 但是str保持不变。
If instead I do this : 如果相反,我这样做:
.....
.....
char str[50];
str[0]=0;
strcat(str, Notation());
.....
.....
str is correctly set. str正确设置。
I am wondering why sprintf doesn't work as expected... 我想知道为什么sprintf不能按预期工作......
You're trying to return an array allocated on stack and its behaviour is undefined. 您正在尝试返回在堆栈上分配的数组,并且其行为未定义。
const char* Notation() const
{
char s[10];
int x=5;
sprintf(s, "%d", x);
return s;
}
here s
isn't going to be around after you've returned from the function Notation()
. 这里s
不会左右你从函数返回后Notation()
If you aren't concerned with thread safety you could make s
static. 如果你不与线程安全而言,你可以让s
静态的。
const char* Notation() const
{
static char s[10];
....
In both cases, it invokes undefined behavior, as Notation()
returns a local array which gets destroyed on returning. 在这两种情况下,它都会调用未定义的行为,因为Notation()
返回一个在返回时被销毁的本地数组。 You're unlucky that it works in one case, making you feel that it is correct. 你不幸的是它在一个案例中起作用,让你觉得它是正确的。
The solution is to use std::string
as: 解决方案是使用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
}
Or using C++ stream as: 或者使用C ++流作为:
std::string Notation() const
{
int x=5;
std::ostringstream oss;
oss << x;
return oss.str();
}
and then: 然后:
char str[50];
sprintf(str, "%s", Notation().c_str());
The benefit (and beauty) of std::ostringstream
(and std::string
) is that you don't have to know the size of output in advance, which means you don't have to use magic number such as 10
in array declaration char s[10]
. std::ostringstream
(和std::string
)的好处( std::ostringstream
)是你不必事先知道输出的大小,这意味着你不必在数组中使用10
等幻数声明char s[10]
。 These classes are safe in that sense. 从这个意义上说,这些类是安全的。
char s[10]
in Notation
is placed on stack so it gets destroyed after exit from Notation
function. Notation
char s[10]
放在堆栈上,因此在退出Notation
函数后会被销毁。 Such variables are called automatic . 这些变量称为自动变量。 You need to save your string in heap using new
: 您需要使用new
将字符串保存在堆中:
char *s = new char[10];
But you have to free this memory manually: 但你必须手动释放这个记忆:
char str[50];
const char *nt = Notation();
sprintf(str, "%s", nt);
printf("%s", str);
delete[] nt;
If you really use C++ then use built-in string
class like Nawaz suggested. 如果你真的使用C ++,那么使用像Nawaz建议的内置string
类。 If you somehow restricted to raw pointers then allocate buffer outside Notation
and pass it as destanation parameter like in sprintf
or strcat
. 如果以某种方式限制为原始指针,则在Notation
外部分配缓冲区,并将其作为destanation参数传递,如sprintf
或strcat
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.