2013-05-25 62 views
0

我有以下代碼:傳遞一個字符串的函數用C

#include <stdio.h> 

char * lookLine (FILE *fichero) 
{ 
    char p[25]; 
    fgets (p, sizeof (p), fichero); 
    return p; 
} 

int main (void) { 
    printf ("%s\n", lookLine (fopen ("suma.c", "r"))); 
    return 0; 
} 

而且我得到以下輸出:

#��x� 

不是很好。我的意圖是打印出名爲「suma.c」的文件的第一行。它應該打印出以下幾點:

#include <stdio.h> 

不過,如果我打印出p字符串的內容到同一個lookFile功能,但它確實是罰款:

#include <stdio.h> 

void lookLine (FILE * fichero) 
{ 
    char p[25]; 
    fgets (p, sizeof (p), fichero); 
    printf ("%s\n", p); 
} 

int main (void) { 
    lookLine (fopen ("suma.c", "r")); 
    return 0; 
} 

和輸出我現在得到的是正確的:

#include <stdio.h> 

我的理由是這樣的:通過使用fgets我救「name.c」的第一行的字符串中的p數組,我返回它的地址,該地址由main中的printf函數的第二個參數獲取。
但我發現,這只是工作的時候我直接使用printf功能到同一個lookLine功能...

請,有人能告訴我這是怎麼回事嗎?

+0

首先,不要使用爲用戶定義的函數讀取的名稱。這是C語言中的一個標準函數,它可能被用作fread,fget等的低級函數。如果沒有其他的東西,那麼讀者將會讀取你的代碼。 – anishsane

+0

可能重複[返回字符\ [\] /字符串從函數](http://stackoverflow.com/questions/14416759/return-char-string-from-a-function) – user93353

+0

其次,我希望這只是一個測試代碼。因爲這有嚴重的泄漏。 – anishsane

回答

6

這是因爲您正在返回指向read函數的本地數組的指針。

請記住,局部變量存儲在堆棧中,包括數組。當函數返回時,編譯器回收堆棧空間以供其他函數調用使用。所以你有一個指向另一個函數內存的指針。

2

陣列p的壽命在return語句結束(技術上p自動存儲持續時間的局部變量,這意味着它的壽命在匹配}結束時)。

程序然後調用未定義的行爲,因爲它使用了不確定的值(從不再指向有效內存的指針讀取)。這就是您可以在read()中打印字符串的原因,但是從main()打印時會發生垃圾。

並注意read是一個POSIX函數,可能會干擾您定義的函數(在嚴格的C89或C99模式下不是問題,但大多數編譯器不是默認情況下)。 [OP在此期間將函數重命名爲lookLine()。]

+0

謝謝你的回答,對我來說很重要的是要知道爲什麼這不起作用。我知道知道堆棧如何工作很重要。我將嘗試堅持使用malloc函數@Jay所說的內容。 –

1

正如Joachin Pileborg所指出的那樣,當您從函數返回時,您試圖返回將被回收的堆棧變量。

相反,您可以嘗試傳遞字符數組,並將其大小作爲函數讀取的輸入。順便說一句,如果除了在讀取函數中調用fgets之外,您不打算做其他任何事情,那麼最好在主函數本身中調用fgets。

如果您在讀取中執行一些額外的邏輯並且您也無法通過緩衝區,並且它的大小作爲讀取函數的輸入,則可以使用malloc分配讀取所需的內存,並將指針返回給調用函數。但是,我個人不會推薦它,因爲最好確保讀取的調用者負責創建和刪除陣列。

相關問題