5

我在这里想念什么?它快把我逼疯了!

我有一个返回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不能按预期工作......

4

3 回答 3

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];
    ....
于 2012-05-27T05:21:24.843 回答
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(and) 的好处(和美)std::string是您不必事先知道输出的大小,这意味着您不必使用诸如10数组声明之类的幻数char s[10]。从这个意义上说,这些类是安全的。

于 2012-05-27T05:22:11.033 回答
1

char s[10]inNotation被放置在堆栈上,因此它在退出Notation函数后被销毁。此类变量称为自动。您需要使用以下命令将字符串保存在堆中new

char *s = new char[10];

但是您必须手动释放此内存:

char str[50];
const char *nt = Notation();
sprintf(str, "%s", nt);
printf("%s", str);
delete[] nt;

如果您真的使用 C++,那么请使用Nawaz建议的内置string类。如果您以某种方式限制为原始指针,则在外部分配缓冲区并将其作为destanation参数传递,例如 in或。Notationsprintfstrcat

于 2012-05-27T05:24:19.163 回答