簡體   English   中英

fgets不讀整行

[英]fgets not reading whole line

我有一個簡單的函數,應該從標准輸入中讀取行並將其放入char數組中,然后在循環中調用此函數,直到輸入EOF。 問題是,對於極長的行(超過10k個字符),fgets僅讀取一些字符並停止,盡管它沒有遇到任何\\ n並且緩沖區有足夠的空間,因此,下次調用此函數將讀取其余的字符的線。 有這種現象的原因嗎(錯誤編寫的代碼,某些緩沖區我不可用)? 有可能修復它嗎? 如果我在代碼中出了點問題,請指出來。

static int getLine(char** line){
    if(feof(stdin)) return 0;
    int len=0;
    char* pointer=NULL;
    int max = 1;
    while(1){
        max+=400;
        *line=(char*)realloc( *line,max);
        if(pointer==NULL)
            pointer=*line;
        if(fgets(pointer, 401, stdin)==NULL)break;
        int len1=strlen(pointer);
        len+=len1;
        if(len1!=400 || pointer[len1]=='\n')break;
        pointer+=len1;
    }
    if(len==0)return 0;
    if((*line)[len-1]=='\n'){
    *line=(char*)realloc(*line, len); 
    (*line)[len-1]='\0';
    return len-1;}//without \n
    return len;
}

我認為您的問題可能是您使用pointer的方式:

char* pointer=NULL;
int max = 1;
while(1){
    max+=400;
    *line=(char*)realloc( *line,max);
    if(pointer==NULL)
        pointer=*line;
    if(fgets(pointer, 401, stdin)==NULL)
        break;
    int len1=strlen(pointer);
    len+=len1;
    if(len1!=400 || pointer[len1]=='\n')
        break;
    pointer+=len1;
}

問題在於realloc()可以更改數據的存儲位置,但是您將其固定在首次指定的位置。 如果您處理大量數據,則很有可能在重新分配時移動數據。 您可以通過跟蹤*line的值來診斷realloc()在每次迭代的realloc()之后打印它)。

修復非常簡單:使用偏移量代替指針作為權威長度,並在每次迭代中設置pointer

enum { EXTRA_LEN = 400 };
size_t offset = 0;
int max = 1;
while (1)
{
    max += EXTRA_LEN;
    char *space = (char*)realloc(*line, max);  // Leak prevention
    if (space == 0)
        return len;
    *line = space;
    char *pointer = *line + offset;
    if (fgets(pointer, EXTRA_LEN + 1, stdin) == NULL)
        break;
    int len1 = strlen(pointer);
    len += len1;
    if (len1 != EXTRA_LEN || pointer[len1] == '\n')
        break;
    offset += len1;
}

對於fgets()的調用,我對使用401而不是400有所保留,但是我沒有精力去確定它是否正確。 我已盡我所能對您的代碼進行了最小限度的更改; 如果我正在完善代碼,我可能會進行更廣泛的更改。 (特別是, max將從0開始,而不是1,並且我不會在對fgets()的調用中使用+1。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM