簡體   English   中英

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

[英]C++ : Why I can't print a const char* with sprintf?

我在這里錯過了什么? 這讓我瘋了!

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

您正在嘗試返回在堆棧上分配的數組,並且其行為未定義。

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];
    ....

在這兩種情況下,它都會調用未定義的行為,因為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 )的好處( std::ostringstream )是你不必事先知道輸出的大小,這意味着你不必在數組中使用10等幻數聲明char s[10] 從這個意義上說,這些類是安全的。

Notation char s[10]放在堆棧上,因此在退出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類。 如果以某種方式限制為原始指針,則在Notation外部分配緩沖區,並將其作為destanation參數傳遞,如sprintfstrcat

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM