如何使用fgets读取长度未知的输入 [英] How to read input of unknown length using fgets

查看:392
本文介绍了如何使用fgets读取长度未知的输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我应该如何使用fgets()读取长输入,我不太明白.

How am I supposed to read long input using fgets(), I don't quite get it.

我写了这个

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

int main()
{
    char buffer[10];
    char *input;
    while (fgets(buffer,10,stdin)){
        input = malloc(strlen(buffer)*sizeof(char));
        strcpy(input,buffer);
    }
    printf("%s [%d]",input, (int)strlen(input));
    free(input);
    return 0;
}

推荐答案

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

int main(void)
{
    char buffer[10];
    char *input = 0;
    size_t cur_len = 0;
    while (fgets(buffer, sizeof(buffer), stdin) != 0)
    {
        size_t buf_len = strlen(buffer);
        char *extra = realloc(input, buf_len + cur_len + 1);
        if (extra == 0)
            break;
        input = extra;
        strcpy(input + cur_len, buffer);
        cur_len += buf_len;
    }
    printf("%s [%d]", input, (int)strlen(input));
    free(input);
    return 0;
}

这是关于最少的更改集,这些更改将为您提供完整的输入行.每次最多增加9个字节的空间.那不是最好的方法,但是要做更好的方法(将分配的空间加倍,并记录分配的数量与使用的数量有关),这需要额外的簿记.请注意,cur_leninput所指向的空间中记录字符串的长度,但不包括终端空值.另请注意,使用extra可以避免分配失败时发生内存泄漏.

This is about the minimal set of changes that will give you the complete line of input. This grows the space by up to 9 bytes at a time; that isn't the best way to do it, but there's extra bookkeeping involved doing it the better ways (doubling the space allocated, and keeping a record of how much is allocated vs how much is in use). Note that cur_len record the length of the string in the space pointed to by input excluding the terminal null. Also note that the use of extra avoids a memory leak on failure to allocate.

strcpy()操作可以合法地替换为memmove(input + cur_len, buffer, buf_len + 1)(在这种情况下,您可以使用memcpy()而不是memmove(),但是它并不总是有效,而memmove()总是可以正常工作,因此使用memmove()更为可靠.

The strcpy() operation could be legitimately replaced by memmove(input + cur_len, buffer, buf_len + 1) (and in this context, you could use memcpy() instead of memmove(), but it doesn't always work while memmove() does always work, so it is more reliable to use memmove()).

具有加倍长度— cur_max变量记录分配了多少空间,而cur_len记录正在使用的空间.

With length-doubling — the cur_max variable records how much space is allocated, and cur_len records how much space is in use.

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

int main(void)
{
    char buffer[10];
    char *input = 0;
    size_t cur_len = 0;
    size_t cur_max = 0;
    while (fgets(buffer, sizeof(buffer), stdin) != 0)
    {
        size_t buf_len = strlen(buffer);
        if (cur_len + buf_len + 1 > cur_max)
        {
            size_t new_len = cur_max * 2 + 1;
            if (buf_len + 1 > new_len)
                new_len = buf_len + 1;
            char *extra = realloc(input, new_len);
            if (extra == 0)
                break;
            input = extra;
            cur_max = new_len;
        }
        strcpy(input + cur_len, buffer);
        cur_len += buf_len;
    }
    printf("%s [%d]", input, (int)strlen(input));
    free(input);
    return 0;
}

这篇关于如何使用fgets读取长度未知的输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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