簡體   English   中英

C中的動態緩沖區fgets

[英]Dynamic buffer fgets in C

我一直在尋找如何使用fgets分配動態緩沖區,但我似乎無法在這個例子中得到它。 該文件有兩個未知長度的數字,由空格分隔。 對於每一行,它會讀取每個字符,直到' '\\n並打印出來。

char *ptr;
char line[MAX];

while(fgets(line, sizeof line , fp) != NULL){
     ptr = line;
     for(i=0; i<2; i++){
        while(*ptr && (*ptr) != ' '){     
             if(*ptr == ' ')
                break;   
             k = (*ptr) - '0';
             if(k != -38)    // wont print '\n'
                printf("%d", k);            
             ptr++;
        }
       while(*ptr && (*ptr) != '\n') {
             if(*ptr == ' '){
                ptr++;
                continue;
             }      
             k = (*ptr) - '0';
             printf("%d", k);       
             ptr++;
     }
   }
}

有人能給我一個如何讓line動態同時仍然使用ptr想法嗎?

我想你想要的是這樣的:

size_t linelen = 80;
char *line = malloc(linelen);

while(magic_reallocating_fgets(&line, &linelen, fp) != NULL) {
    /* ... do whatever you want with line ... */
}

但是,當然,64,000美元的問題是, magic_reallocating_fgets看起來像什么? 它是這樣的:

char *magic_reallocating_fgets(char **bufp, size_t *sizep, FILE *fp) {
    size_t len;
    if(fgets(*bufp, *sizep, fp) == NULL) return NULL;
    len = strlen(*bufp);
    while(strchr(*bufp, '\n') == NULL) {
        *sizep += 100;
        *bufp = realloc(*bufp, *sizep);
        if(fgets(*bufp + len, *sizep - len, fp) == NULL) return *bufp;
        len += strlen(*bufp + len);
    }
    return *bufp;
}

這不是真正完整的代碼,它幾乎是偽代碼。 我為你做了兩件事作為練習:

它沒有對mallocrealloc調用進行錯誤檢查。

它的效率非常低,因為在它讀取的每一行上只有兩個額外的通道:計算字符數,然后再查找'\\n' (事實證明, fgets的界面並不適合這種工作。)

在glibc> = 2.7或POSIX.1-2008支持的系統上,我認為你想要的可以使用:

char *line;
while (fscanf(f, "%m[^\n]\n", &line) == 1) {
    /* do stuff with line */
    free(line);
}

這在我的Linux系統上運行良好,但在Windows Universe中,Microsoft Visual C ++既不支持%m,也不支持任何我能找到的等效項。

您無法在C中運行時更改數組的大小。這是非法的。 這是因為數組是從堆棧中分配的。 要使大小是動態的,您必須聲明一個指針,並為其動態分配內存。 這些數據是從堆中分配的。

您可以使用realloc更改已分配內存的大小。

int lineLen = 80;
char *line;
line = (char *)malloc(sizeof(char) * 80);
if (line == NULL) {
    // Something went horribly wrong
    exit(1);
}
while (fgets(line, lineLen, fp)) {
    // Do something to find the size
    line = (char *)realloc(line, sizeof(char) * newLen);
    if (line == NULL) {
        // Something went horribly wrong
        exit(1);
    }
}

但是,分配和重新分配內存是一項相當昂貴的操作。 因此,如果您可以安全地執行此操作,則可以通過選擇較大的緩沖區大小來提高效率。 如果你有一個短循環,那么它可能不足以擔心,但可能不建議不斷改變緩沖區的大小。

暫無
暫無

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

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