簡體   English   中英

用於讀取輸入的動態緩沖區大小

[英]dynamic buffer size for reading input

我正在嘗試創建一個程序,該程序將從stdin逐行讀取,在該行中搜索給定單詞的開頭和結尾,並輸出所有匹配的單詞。 這是代碼:

int main()
{
    char buffer[100];
    char **words = NULL;
    int word_count = 0;

    while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
        int length = strlen(buffer);
        if (buffer[length - 1] == '\n') {
            word_count = count_words(buffer, FIRSTCHAR);
            if (word_count > 0) {
                words = get_words(buffer, FIRSTCHAR, LASTCHAR);
                for (int i = 0; i < word_count; ++i) {
                    printf("%s\n", words[i]);
                    free(words[i]);
                }
                free(words);
            }
        }
    }
    return 0;
}

我可以使用基本功能,但是我依賴具有固定緩沖區大小的fgets()。 我想要動態分配一個內存緩沖區,其大小基於每行的長度。

我只能看到一種解決它的方法,該方法是使用fgetc遍歷輸入並遞增一個計數器直到行尾,然后使用該計數器代替sizeof(buffer) ,但是我不知道該怎么做。 fgetc讀取正確的相關行。

有解決這個問題的聰明方法嗎?

但我依賴具有固定緩沖區大小的fgets() 我想動態分配一個內存緩沖區,其大小基於每行的長度

我確實為另一個SO答案寫了一個fgets版本,該答案讀取了整行並返回了包含整行內容的malloc分配指針。 這是代碼:

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

char *fgets_long(FILE *fp)
{
    size_t size = 0, currlen = 0;
    char line[1024];
    char *ret = NULL, *tmp;

    while(fgets(line, sizeof line, fp))
    {
        int wholeline = 0;
        size_t len = strlen(line);

        if(line[len - 1] == '\n')
        {
            line[len-- - 1] = 0;
            wholeline = 1;
        }

        if(currlen + len >= size)
        {
            // we need more space in the buffer
            size += (sizeof line) - (size ? 1 : 0);
            tmp = realloc(ret, size);
            if(tmp == NULL)
                break; // return all we've got so far
            ret = tmp;
        }

        memcpy(ret + currlen, line, len + 1);
        currlen += len;

        if(wholeline)
            break;
    }

    if(ret)
    {
        tmp = realloc(ret, currlen + 1);
        if(tmp)
            ret = tmp;
    }

    return ret;
}

訣竅是檢查是否已讀取換行符。 如果已讀取,則可以返回緩沖區,否則它將使用sizeof line重新分配緩沖區更多字節,並將其追加到緩沖區。 您可以根據需要使用此功能。

另一種選擇是,如果您使用的是POSIX系統和/或正在使用GNU GCC進行編譯,則也可以使用getline

void foo(FILE *fp)
{
    char *line = NULL;
    size_t len = 0;

    if(getline(&line, &len, fp) < 0)
    {
        free(line); // man page says even on failure you should free
        fprintf(stderr, "could not read whole line\n");
        return;
    }

    printf("The whole line is: '%s'\n", line);

    free(line);

    return;
}

函數: getline()您的需求。 語法:

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

該函數在stdio.h頭文件中公開,通常需要類似以下內容: #define _POSIX_C_SOURCE 200809L#define _GNU_SOURCE作為調用getline()的文件的第一行

強烈建議您閱讀/理解`getline()的MAN頁面,以獲取所有骯臟的細節。

暫無
暫無

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

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