1. 程式人生 > >c語言實現getline函式

c語言實現getline函式

getline函式可以獲取檔案中的一行資料。

原函式形式為
ssize_t getline(char **linepter,size_t *n,FILE *stream)

返回型別ssize_t為有符號整形,其值為獲取的字元數,檔案結束則返回-1,包括換行符’\n’,但不包括字串結束符’\0’。linepter用來儲存獲得的字串,size_t為無符號整形表示linepter的位元組數。當*linepter為空時函式則動態為其分配空間,注意要將size_t值賦0。當linepter的空間不足時,函式會通過realloc,重新分配更大的空間。stream為檔案指標,用於讀取檔案。

在瞭解了系統的getline函式後,根據其功能自己進行了實現。

ssize_t mygetline(char** line,size_t *n,FILE *fp)
{
    char *buf = *line;
    ssize_t c,i=0;//i來記錄字串長度,c來儲存字元
    if(buf==NULL||*n==0)
    {
        *line = malloc(10);
        buf = *line;
        *n = 10;
    }
    //buf為或n為0時動態為期分配空間
    while((c=fgetc(fp))!='\n')
    {
        if(c==EOF)
            return
-1; if(i<*n-2)//留2個空間給\n和\0 { *(buf+i++)=c; } else { *n = *n+10; buf = realloc(buf,*n);//空間不足時,重新進行分配 *(buf+i++)=c; } } *(buf+i++)='\n'; *(buf+i)='\0'; return i; }

字元’\n’為一行的結束,EOF是檔案結束標誌。

測試程式碼:

int main()
{
    FILE *fp = fopen("F1","r");
    if(fp==NULL)
    {
        exit(EXIT_FAILURE);
    }
    char *buf = NULL;
    size_t i=0;
    ssize_t l;

    while((l=mygetline(&buf,&i,fp))!=-1)
    {
        printf("str:%s len:%d i:%u\n",buf,l,i);
        //列印字串buf,返回字串長度l和buf分配的位元組數i
        free(buf);
        buf = NULL;
        i = 0;
    }
    free(buf);
    fclose(fp);
    exit(EXIT_SUCCESS);
    return 0;
}

這裡buf來接收資料,通過函式來給buf分配空間,也可在外部自己來分配空間,i為buf的位元組數,當空間不夠時函式中會通過realloc來增加空間,每次增加10個位元組。

執行環境為linux red hat7,F1是在vim中寫入資料的檔案。
檔案內容:這裡寫圖片描述
在vim中每行字元的最後實際還有一個換行符\n,檔案的最後是結束符EOF。
下面是執行測試程式後的結果:
這裡寫圖片描述

可以看到函式會動態為buf分配空間,每次會增加10個,而字串長度會比實際看到的字元多一個即是換行符\n。

以上基本實現了getline函式的功能,實現和測試是需要注意一下幾點:1.函式中迴圈的結束判定條件和變數的範圍,避免死迴圈和越界2.儲存空間的動態分配和釋放3.引數以及返回值的形式。