2011-10-04 55 views
2

我正在參加我的第一個C編程課程,並且遇到了一個嘗試編寫一次讀取文本文件的函數的問題。這裏是我的代碼:發送一個函數的字符串指針

#define LINELENGTH 81 

int getLine(char* line, FILE* file) { 

    if (line == NULL) { 
     line = malloc(sizeof(char) * LINELENGTH); 
    } 

    fgets(line, LINELENGTH, file); 
    int length = strcspn(line, "\n"); 
    if (line[length] == '\n') { 
     line[length] = '\0'; 
     line = realloc(line, sizeof(char) * (length + 1)); 
     return length; 
    } else { 
     char* addThis = NULL; 
     int addedLength = getLine(addThis, file); 
     length += addedLength; 
     line = realloc(line, sizeof(char) * length); 
     strcat(line, addThis); 
     free(addThis); 
     addThis = NULL; 
     return length; 
    } 
} 

int main() { 
    FILE *text = fopen("test.txt", "r"); 
    char* line = NULL; 
    getLine(line, text); 
    printf("The first line is \"%s\"", line); 
    fclose(text); 
    free(line); 
    return 0; 
} 

我的測試輸入文件現在只包含一個單一的線,「測試」

當我運行該程序,我得到「第一行是‘(空)’」。不是我所希望的。當我通過調試器中的函數時,getLine中的所有內容似乎都可以正常工作。但是,當函數返回我剩下的所有東西都是null的時候。

任何幫助表示讚賞。謝謝。

回答

2

getLine的調用按值傳遞char*指針。該函數內的line賦值不會導致將分配的指針返回給調用者。功能聲明應該可能是:

int getLine(char** line, FILE* file) {... 

然後將結果分配給*line。而調用該函數將需要通過地址:

getLine(&line, text); 

你也可以使用一個局部變量的函數內使用,然後最終結果返回之前分配給*line。這可能會使代碼更容易理解。否則,每次使用line時,都需要對指針取消引用,並且它(只是我的意見)會變得有點混亂。因此,可以將函數定義中的參數更改爲getLine(char** retLine, ...)。然後聲明char* line;形式的局部變量。然後前return陳述,爲它分配:

*retLine = line; 

一個非常不完整的例子:

int getLine(char **retLine, FILE *file) {  
    *retLine = NULL; // make sure we don't return garbage if error occurs 
    char *line = malloc(...); 
    // do stuff with line, fill it up, etc. 
    ... 
    // assign the final result to the output param 
    *retLine = line; 
    return length; 
} 

這基本上是一個優先問題。否則,必須完成取消引用。例如,

*line = malloc(...); 
int length = strcspn(*line, ...); 

+0

感謝您的快速響應。我還沒有處理指向指針的指針,我發現它有點混亂。我正在尋找一些代碼示例... – jobrien929

+0

@ jobrien929:我添加了更多的信息,可能(或可能不會)幫助清理我想說的話。 –

+0

它絕對做到了。我剛剛得到它的工作。謝謝您的幫助。 – jobrien929

1

「行」是一個指針,你的getline函數的唯一改變「線」,它不改變「行」指針時,它自身的副本值。對於你的情況,你應該嘗試

int main() { 
    // .. 
    line = malloc(sizeof(char) * LINELENGTH); 
    getLine(line, text); 
    // .. 
} 
0

你需要改變你的getLine功能,你怎麼稱呼它,以便它可以修改傳遞給它的指針的方式。現在,當您分配或重新分配行時,您只修改函數內的本地副本。

而不是

int getLine(char* line, FILE* file) { 

你需要

int getLine(char **line, FILE *file) { 

然後,內getLine,您需要取消引用line無論你用它來與它指向的指針,例如工作:

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

...和...

(*line)[length] = '\0'; 

...和line的其他用途類似。

如果你可以擺脫遞歸和strcat你也可以提高你的函數的效率,雖然上面的變化應該可以使它工作。

0

好像烏爾周圍發生的很長的路要走,我會做這樣的事情:

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

char line[1000]; 

int main() 
{ 
FILE *file; 
file = fopen("test.txt", "r"); 

fgets(line, sizeof(line), file); 
printf("First line: %s", line); 
memset(line, 0, strlen(line)); 
fclose(file); 
return 0; 
} 

,並在需要時您可以納入到這一個功能。 或者如果u想擁有它列出整個文件,你可以簡單地這樣做:

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

char line[1000]; 

int main() 
{ 
FILE *file; 
file = fopen("test.txt", "r"); 

while(!feof(file)) 
{ 
fgets(line, sizeof(line), file); 
printf(line); 
memset(line, 0, strlen(line)); 
} 

fclose(file); 
return 0; 
} 
0

考慮到你有沒有做過指針的指針。

我建議改變方法的簽名如下:

char* getLine(int *len, FILE* file); 
// instead of assigning the value to line like in your case, return it. 

用法是:

int main() { 
    . 
    . 
    . 
    int length; 
    char* line = NULL; 
    line = getLine(&len, text); 
    . 
    . 
} 

而且,我看你是不是使用的返回值即的長度在main()中的行。因此,您可以完全省略長度字段並具有如下方法定義:

char* getLine(FILE* file); 
相關問題