2009-01-30 98 views
2

任何人都可以向我解釋爲什麼這不起作用?幫助自定義getline()函數

#include <stdio.h> 
#include <stdlib.h> 

char *getline(int lim) 
{ 
    char c; 
    int i; 
    char *line; 
    line = malloc(sizeof(char) * lim); 


    i = 0; 
    while((c = getchar()) != '\n' && c != EOF && i < lim-1) 
    { 
     *line = c; 
     line++; 
     i++; 
    } 
    *line = '\0'; 
    printf("%s", line); 
    return line; 
} 

我現在不擔心返回值 - 只是原因爲何printf("%s", line)不工作。

謝謝!

編輯:固定爲line = malloc(sizeof(char) * lim);但它仍然無法正常工作。

解決方案:*line的地址在整個函數中遞增。當它傳遞到printf()時,*line指向'\ 0',因爲這是其地址遞增的地方。使用臨時指針將malloc()分配的原始地址存儲到*line,然後將該指針傳遞到printf(),允許函數沿指針移動。

+0

sizeof char的定義是1,所以這是多餘的。 – 2009-01-30 17:24:07

+0

@Charles Bailey:是的,但我認爲它應該保持這種狀態,因爲當前版本更加明確。無論如何,編譯器會將其全部轉換爲常量。 – 2009-01-30 17:45:03

+0

那麼,對於使用sizeof * lim來防止未來更改的魯棒性有一個爭論,但是使用sizeof(char)只是浪費了輸入(恕我直言)。 – 2009-01-30 17:57:17

回答

5

因爲你只對該行的單個字符分配足夠的空間:

line = malloc(sizeof(char)); 

而且你printf語句之前,這是獲得充滿\0

我猜你想改變這個行:

/* Allocate enough room for 'lim' - 1 characters and a trailing \0 */ 
line = malloc(sizeof(char) * lim); 

甚至更​​好:

char *line, *tmp; 
tmp = line = malloc(sizeof(char) * lim); 

,然後使用你所有的指針數學tmp,這樣line仍將指向你的字符串的開始。

而且我知道它在你的開發早期,但你會想確保你free()你的存儲器malloc()


這裏是你的函數的一個工作版本,包括我的修改建議:

#include <stdio.h> 
#include <stdlib.h> 

char *getline(int lim) 
{ 
    char c; 
    int i; 
    char *line, *tmp; 
    tmp = line = malloc(sizeof(char) * lim); 

    i = 0; 
    /* NOTE: 'i' is completely redundant as you can use 'tmp', 
    * 'line,' and 'lim' to determine if you are going to 
    * overflow your buffer */ 
    while((c = getchar()) != '\n' && c != EOF && i < lim-1) 
    { 
     *tmp = c; 
     tmp++; 
     i++; 
    } 
    *tmp = '\0'; 
    printf("%s", line); 
    return line; 
} 
3

它看起來像你正在打印一個零長度的字符串。

*line = '\0'; 
printf("%s", line); 

我假定你要存儲什麼line最初(從malloc返回)和打印。

1

你似乎只有一個字符都分配了足夠的空間。您的意思是不是以下內容:

line = malloc(lim * sizeof(char)); 

而且,你不想讀的每個字符後更改line。使用下面的塊爲您while循環,而不是:

*(line + i) = c; 
i++; 

最後,爲空 - 終止字符串,使用:

*(line + i) = '\0'; 
0

你還覆蓋內存,你沒有自己。你正在使用一個字符,將*行設置爲c,然後增加行並重復。

1

更新時間 - 這是一個簡單的錯字錯,但你沒有投我下來就可以了

,而不是

 char *line= malloc(sizeof(char)); 

嘗試

int space= //number of how many characters you need on the line 
    char *line= malloc(sizeof(char)*space); 

對不起我的意思

char *line= malloc(sizeof(char)*lim) 
0

您n瞭解指針的概念,以及它如何與緩衝區不同。 在您的代碼中,您同時將「行」視爲指針和緩衝區。

1

每個人都已經覆蓋了這些點,但這裏是整個事情都放在一起:

編輯:改進代碼有點

#include <stdio.h> 
#include <stdlib.h> 

char *getline(int lim) 
{ 
    char *result = malloc(sizeof(char) * lim); // allocate result buffer 

    int i = 0; 
    char c; 
    char *line = result; 
    while((c = getchar()) != '\n' && c != EOF && i < lim-1) 
    { 
     *line = c; 
     line++; 
     i++; 
    } 
    *line = '\0'; 

    printf("%s", result); // print the result 
    return result; // return the result buffer (remember to free() it later) 
} 
0

你兩點犯錯(但你可以說相同的錯誤或兩個,它取決於你)。首先你的指針應該增加,如

*(line + i)= c; 由於這個原因,當你在循環結束時設置Null字符時,你實際上是在說編譯器將指針指向這個poistion。所以指針只指向Null字符串而不是整個字符串。因爲它在循環的每一步都會不斷移動。 所以當你試圖打印指針沒有什麼可打印的。所以,如果你改變你的語句在指針的循環中,並把值賦給一個表達地址,而不是實際移動指針,那麼你的問題就會解決。

注意。如果您更改該行,那麼您還需要修改您的Null終結符賦值,如下所示; *(line + limit)='\ 0';