2017-07-21 31 views
0

這是我第一次發佈在這裏:) 我試過在這裏搜索,但未能找到我的具體問題的答案。 我很新的C,主要是用C#到現在爲止, 所以整個指針的想法是不是我的一塊蛋糕..字符*通過函數打印什麼都沒有

我試圖創建它變成一個字符串的整數的函數, 我succeded直到返回值的部分。 我不明白爲什麼在函數結束時,字符串正在正確打印,但主函數不是這種情況。如果有人可以看一下代碼並向我解釋爲什麼它不起作用(爲什麼它在主函數中什麼都不打印),這將不勝感激。

主要功能:

int main() 
{ 
    printf("%s", int_to_string(4058)); 
    return 0; 
}; 

詮釋爲String功能:

char* int_to_string(int n) 
    { 
    int len = int_length(n); 
    char str[len]; 
    int count = 1; 
    while (n != 0) 
    { 
     char c = (n % 10) + '0'; 
     str[len - count] = c; 
     count++; 
     n /= 10; 
    } 
    char* s = str; 
    printf(s); // Works perfectly, prints the number as a string of characters 
    return s; 
}; 

分Func鍵 - 詮釋長度功能:

int int_length(int s) 
{ 
    int count = 0; 
    while(s != 0) 
    { 
     count++; 
     s /= 10; 
    } 
    return count; 
}; 

你的幫助將真正的讚賞!

+1

你欺騙了編譯器,但是你沒有解決這個問題(*'return str;'沒有警告*不能工作)。請閱讀關於堆棧和局部變量。對此有很多重複的內容。 –

+0

''我試過在這裏搜索,但未能找到我的具體問題的答案。' - 這是非常頻繁地發佈。返回並使用指向本地變量的指針是UB。 –

+0

'char str [len];' - >'static char str [32];'並將NUL字符設置爲字符串結尾。 – BLUEPIXY

回答

1

您要返回本地變量的地址,即str。一旦函數退出,該地址不再有效。嘗試取消引用該地址將調用undefined behavior

您應該更改函數以聲明strstatic,以便在函數退出後其生存期存在。在這種情況下,您需要將數組的大小設置爲固定大小,因此至少需要12個字節,這應該足夠大以容納32位int的字符串表示形式。

+0

它工作完美,謝謝! :) –

+0

@ M.Raz很高興我能幫到你。如果您覺得它有用,請隨時[接受此答案](https://stackoverflow.com/help/accepted-answer)。 – dbush

1

您的程序的主要問題是您正在返回對自動字符數組的引用。這意味着數組在函數返回後死亡,因此在主函數中不可訪問。你可以閱讀更多關於變量範圍的內容,以更好地理解這一點。

就目前而言,您有兩種解決此問題的方法。

  1. 使用堆 - 您可以使用malloc函數在堆上分配字符數組。在堆中分配的任何內存都保證保持在範圍內直到程序退出或直到它被明確釋放。這樣,你也必須記住它是用做後釋放所分配的內存

    char *str = malloc(len+1); //As suggested by BLUEPIXY size needs to be len+1 to accomodate the \0 
    

    - 所以您可以在數組聲明改變。因此,在主,你將不得不改變

    char *str = int_to_string(5098); 
    printf("%s", str); 
    free(str); 
    
  2. 分配的內存中調用者 - 如果你不想進入堆中分配內存,後來釋放它的混亂。您可以在來電者分配內存並把它傳遞給你的函數作爲

    char str[len+1]; // Same reasoning as before for len+1 
    printf("%s", int_to_string(5098, str)); 
    

    ,你的功能將變爲

    char* int_to_string(int n, char *str){ 
        // No need to declare str now. Start using as before 
        ... 
        return str; 
    } 
    

    在這種情況下,你不必擔心,因爲釋放內存當main返回時它會自動超出範圍。

也與您的問題無關您的代碼有一個致命錯誤。你不是null終止你的字符串。當傳遞到printf%s格式字符串修飾符時,這將導致未定義的行爲。

因此,一個簡單的解決將是

str[count] = '\0'; 

只是在函數的末尾。 我希望這可以幫助。

+0

@BLUEPIXY我認爲這是最好的解決方案,因爲使變量靜態會導致問題字母,這個答案最適合現實世界場景。你不這麼認爲嗎? – Omkar

+0

@BLUEPIXY謝謝,我已經更新了示例以騰出空間來容納空終止符。至於能夠像'printf(「%s」,int_to_string(4058))那樣使用它'',我不確定這是否真的很重要。顯然,OP不僅僅是打印字符串。否則他們可以使用'%d'。也許這就是我的想法,但對於使用靜態數組的人來說,這似乎更清晰。 –

+0

您的解決方案,先生,非常詳細和美麗。我發現它對我的問題很有幫助,而且還幫助我解決了另一個問題。謝謝! –