我在这里缺少什么?这让我疯了!
我有一个返回 const char *
的函数const char* Notation() const
{
char s[10];
int x=5;
sprintf(s, "%d", x);
return s;
}
现在我正在执行此代码的另一部分:
.....
.....
char str[50];
sprintf(str, "%s", Notation());
.....
.....
但 str 保持不变。
如果我这样做:
.....
.....
char str[50];
str[0]=0;
strcat(str, Notation());
.....
.....
str 已正确设置。
我想知道为什么 sprintf 无法正常工作......
答案 0 :(得分:9)
您正在尝试返回在堆栈上分配的数组,其行为未定义。
const char* Notation() const
{
char s[10];
int x=5;
sprintf(s, "%d", x);
return s;
}
从函数s
返回后,此处Notation()
不会出现。如果您不关心线程安全性,可以使s
静态。
const char* Notation() const
{
static char s[10];
....
答案 1 :(得分: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
}
或者使用C ++流:
std::string Notation() const
{
int x=5;
std::ostringstream oss;
oss << x;
return oss.str();
}
然后:
char str[50];
sprintf(str, "%s", Notation().c_str());
std::ostringstream
(和std::string
)的好处(和美)是你不必提前知道输出的大小,这意味着你不必使用幻数例如数组声明10
中的char s[10]
。从这个意义上讲,这些课程是安全的。
答案 2 :(得分:1)
char s[10]
中的 Notation
被置于堆栈中,因此在退出Notation
函数后会被销毁。这些变量称为automatic。您需要使用new
:
char *s = new char[10];
但你必须手动释放这个记忆:
char str[50];
const char *nt = Notation();
sprintf(str, "%s", nt);
printf("%s", str);
delete[] nt;
如果您真的使用C ++,那么请使用内置的string
类Nawaz建议。如果以某种方式限制为原始指针,则在Notation
之外分配缓冲区并将其作为 destanation 参数传递,如sprintf
或strcat
。