用于读取输入的动态缓冲区大小 [英] dynamic buffer size for reading input

查看:70
本文介绍了用于读取输入的动态缓冲区大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个程序,该程序将从stdin逐行读取,在该行中搜索给定单词的开头和结尾,并输出所有匹配的单词.这是代码:

I am trying to create a program that will read line by line from stdin, search that line for the start and end of a given word and output all the matching words. Here is the code:

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().我想根据行的长度动态分配一个内存缓冲区.

I got the basic functionality working, but I am relying on fgets() with a fixed buffer size. What I would like is to dynamically allocate a memory buffer with a size based on the length of each line.

我只能看到一种解决它的方法,该方法是使用 fgetc 对输入进行迭代,并增加一个计数器直到行尾,然后使用该计数器代替 sizeof(缓冲区),但我不知道如何让fgetc读取正确的相关行.

I can only see one way of going about solving it, which is to iterate over input with fgetc and increment a counter until end of line and use that counter in place of sizeof(buffer), but I don't know how I would get fgetc to read the correct relevant line.

有解决这个问题的聪明方法吗?

Is there any smart way of solving this?

推荐答案

但是我依赖具有固定缓冲区大小的 fgets().我想根据行的长度动态分配大小的内存缓冲区

but I am relying on fgets() with a fixed buffer size. What I would like is to dynamically allocate a memory buffer with a size based on the length of each line

我确实为另一个SO答案写了 fgets 版本,该答案读取整行并返回 malloc 分配了带有整行内容的指针.这是代码:

I did wrote a version of fgets for another SO answer that reads the whole line and returns a malloc allocated pointer with the contents of the whole line. This is the code:

#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 个更多的缓冲区重新分配缓冲区个字节,并将其附加到缓冲区.您可以根据需要使用此功能.

The trick is to check if the newline was read. If it was read, then you can return the buffer, otherwise it reallocates the buffer with sizeof line more bytes and appends it to the buffer. You could use this function if you like.

另一种选择是,如果您使用的是POSIX系统和/或正在使用GNU GCC进行编译,则您也可以使用 getline .

An alternative would be if you are using a POSIX system and/or are compiling with GNU GCC, then you can use getline as well.

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;
}

这篇关于用于读取输入的动态缓冲区大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆