2012-09-29 111 views
1

我需要一個函數/方法,它將接受一個char數組並將其設置爲從stdin讀取的字符串。它需要返回讀取的最後一個字符作爲它的返回類型,所以我可以確定它是否到達一行的結尾或文件標記的結尾。自定義getLine()函數c

這裏是我到目前爲止,我有種基於它關閉的代碼here

更新:我改變了它,但現在它只是崩潰後擊中後的文本輸入。我知道這種方式效率低下,char不是EOF檢查的最佳選擇,但現在我只是試圖讓它返回字符串。我需要它以這種方式來做,而不是其他方式。我需要該字符串是行的確切長度,並返回一個值,該值是換行符或EOF int,我相信它仍然可以在char值中使用。

這個程序是用C不是C++

char getLine(char **line); 

int main(int argc, char *argv[]) 
{ 
    char *line; 
    char returnVal = 0; 

    returnVal = getLine(&line); 
    printf("%s", line); 

    free(line); 

    system("pause"); 
    return 0; 
} 

char getLine(char **line) { 
    unsigned int lengthAdder = 1, counter = 0, size = 0; 
    char charRead = 0; 

    *line = malloc(lengthAdder); 
    while((charRead = getc(stdin)) != EOF && charRead != '\n') 
    { 
     *line[counter++] = charRead; 
     *line = realloc(*line, counter); 
    } 

    *line[counter] = '\0'; 

    return charRead; 
} 

感謝您的幫助提前!

+1

你想要C或C++嗎? *適當*解決方案在每種語言中都非常不同。還要注意,比讀取的最後一個字符的值更有趣的是讀取的字符數。您始終可以在讀取字符串中查看該位置以確定該字符是什麼。另外,多個'realloc'可能效率低下。 –

+0

除了H2CO3所說的內容之外,儘管你聲明它返回一個'char',但你不會從'getLine'返回任何東西。此外,你不應該爲每個角色「重新分配」,而是以大小合理的塊來完成。 'line = realloc(line,counter);''表示如果'realloc'失敗,則失去對內存的引用,使用臨時文件保存'realloc'的結果並檢查它是否爲'NULL'。 –

回答

0

你的關鍵的問題是,指針值不傳播出函數getline()功能。解決方法是將指針指針指針改爲函數作爲參數 - 將其調用爲getLine(&line);,而將函數定義爲採用參數char **line。在該函數中,在您現在使用的所有地方,您可以使用*行來代替,即將指針取消引用到指針,並使用變量的值處理main()其中指針線索。希望這不是太混亂。 :-)嘗試在一張紙上繪製它。

(A棘手的部分 - 你必須改變line[counter](*line)[counter]因爲你第一需要取消引用字符串指針,只有然後在字符串中訪問一個特定的字符。)

有一對夫婦的其他問題與您的代碼:

  • 您使用焦炭的類型charRead。然而,EOF常量不能使用焦炭代表,你需要使用INT - 既作爲charRead的類型和函數getline()的返回值,因此,你實際上可以換行之間distringuish和文件結尾。
  • 您忘記返回從您的getLine()函數中讀取的最後一個字符。 :-)
  • 在每次添加字符後,您正在重新分配緩衝區。這不是非常有效,因此是一個相當醜陋的編程習慣。使用另一個變量來跟蹤分配的空間量並不難,然後(i)從分配合理的內存塊開始,例如, 64字節,所以理想情況下你永遠不會重新分配(ii)只有當你需要基於計數器和你的分配大小跟蹤器的比較時才擴大分配。兩種重新分配策略是常見的 - 要麼將分配量擴大一倍,要麼通過固定的步驟增加分配。
+0

我知道它現在效率很低,我只是想讓它返回字符串atm。當我得到它返回字符串時,我會擔心一切。我將參數更改爲** char,並將其傳遞給地址,並將其轉換爲函數內的所有內容,並通過*行將其設置爲所有內容。現在它只是在打開時崩潰 – Tookie

+0

一個棘手的部分 - 你必須將'line [counter]'改成'(* line)[counter]',因爲你首先需要將指針取消引用到字符串,只有* then *訪問字符串中的特定字符。這有幫助嗎?如果沒有,確切地說它崩潰的地方?嘗試在調試器中運行它。 –

+0

是的,我改變了它,它輸入文本後崩潰。之前,如果我把一個printf函數,它確實得到了字符串就好了,但不會返回它。我知道我是通過價值傳遞它的,所以它不會被保存到原來的。現在我可以不檢查它了。更新後的代碼位於 – Tookie

2

你分配的malloc()的結果的line本地副本,所以getLine()函數返回後它不會修改(儘管你認爲這是)。你所要做的就是要麼返回它(而不是使用一個輸出參數)或通過其地址(「通過引用」傳遞):

void getLine(char **line) 
{ 
    *line = malloc(length); 

    // etc. 
} 

,並調用它像這樣:

char *line; 
getLine(&line); 
+0

我改變了它,但現在它輸入數據時崩潰。更改後的代碼在操作中更新。 – Tookie

+0

@Tookie因此,我們不會爲您編寫完整的解決方案,對不起。這是你錯過的基本想法 - 除此之外,請使用調試器學習,谷歌關於指針等的好教程。 – 2012-09-29 23:45:13

0

您使用realloc的方式不正確。如果它返回NULL那麼內存塊將會丟失。

最好是用這種方式來使用realloc

char *tmp; 
... 
tmp = realloc(line, counter); 
if(tmp == NULL) 
    ERROR, TRY TO SOLVE IT 
line = tmp; 
+0

是的,但這並沒有回答這個問題。這應該是一個評論,而不是一個答案。 – 2012-09-29 23:03:27