在C中从文件中读取一行,动态 [英] Reading a line from file in C, dynamically

查看:188
本文介绍了在C中从文件中读取一行,动态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

int main()
{
    FILE *input_f;

    input_f = fopen("Input.txt", "r"); //Opens the file in read mode.
    if (input_f != NULL)
    {
        char line[2048];

        while( fgets(line, sizeof line, input_f) != NULL )
        {
            //do something
        }
        fclose(input_f); //Close the input file.
    }
    else
    {
        perror("File couldn't opened"); //Will print that file couldn't opened and why.
    }
    return 0;
}

您好。我知道我可以在C中逐行读取这段代码,但是我不想限制行大小,就像在2048年的代码中一样。

Hi. I know I can read line by line with this code in C, but I don't want to limit line size, say like in this code with 2048.

我以为关于使用malloc,但是我在读取之前不知道行的大​​小,所以IMO不能完成。

I thought about using malloc, but I don't know the size of the line before I read it, so IMO it cannot be done.

有没有办法不要限制行大小?

Is there a way to not to limit line size?

这个问题只是为了我的好奇心,谢谢你。

This question is just for my curiosity, thank you.

推荐答案

当您动态分配内存时,您将要更改:

When you are allocating memory dynamically, you will want to change:

char line[2048];

#define MAXL 2048           /* the use of a define will become apparent when you  */
size_t maxl = MAXL;         /* need to check to determine if a realloc is needed  */
char *line = malloc (maxl * sizeof *line);
if (!line)                  /* always check to insure allocation succeeded */
    ...error.. memory allocation failed

您阅读了( maxl -1 )字符或换行符(如果使用 fgetc 等等)或读取行,然后检查是否 line [strlen(line) - 1] ==' \\ n'来确定是否阅读整行(如果使用 fgets )。 (POSIX要求所有行以换行结束)如果您阅读 maxl characters( fgetc )或没有读取换行符( fgets ),那么这是一个短读,还有更多的字符。您的选择是 realloc (通常将尺寸翻倍),然后重试。要realloc:

You read read up to (maxl -1) chars or a newline (if using fgetc, etc..) or read the line and then check whether line [strlen (line) - 1] == '\n' to determine whether you read the entire line (if using fgets). (POSIX requires all lines terminate with a newline) If you read maxl characters (fgetc) or did not read the newline (fgets), then it is a short read and more characters remain. Your choice is to realloc (generally doubling the size) and try again. To realloc:

char *tmp = realloc (line, 2 * maxl)
if (tmp) {
    line = tmp;
    maxl *= 2;
}

注意:永不使用原始指针重新分配例如 line = realloc(line,2 * maxl)因为如果 realloc 失败,则内存被释放,指针集到 NULL ,您将丢失行中存在的任何数据。另请注意, maxl 每次你 realloc 时,通常会翻倍,但是你可以随意选择你喜欢的任何大小增加的方案(如果你关心所有新的内存分配,您可以使用memset将新分配的空间初始化为零/ null。在某些情况下,您希望确保始终为 null终止

Note: never reallocate using your original pointer (e.g. line = realloc (line, 2 * maxl) because if realloc fails, the memory is freed and the pointer set to NULL and you will lose any data that existed in line. Also note that maxl is typically doubled each time you realloc. However, you are free to choose whatever size increasing scheme you like. (If you are concerned about zeroing all new memory allocated, you can use memset to initialize the newly allocated space to zero/null. Useful in some situations where you want to insure your line is always null-terminated)

这是基本的动态分配/重新分配方案。请注意,在阅读完整的行之前,您正在阅读,因此您将需要重组你的循环测试,最后,由于你分配了内存,你负责释放内存当你完成它一个你不能生活的工具是 valgrind (或类似的内存检查器),以确认你没有泄漏内存。

That is the basic dynamic allocation/reallocation scheme. Note you are reading until you read the complete line, so you will need to restructure your loop test. And lastly, since you allocated the memory, you are responsible for freeing the memory when you are done with it. A tool you cannot live without is valgrind (or similar memory checker) to confirm you are not leaking memory.

提示如果您正在阅读并希望确保您的字符串始终为空终止,则在分配内存块之后,零( 0 )所有字符。如前所述, memset 可用,但如果您选择 calloc 而不是 malloc 它将为您的内存为零。然而,在 realloc 中,新空间不为零,因此无论什么功能都需要调用 memset 最初分配了块。

Tip if you are reading and want to insure your string is always null-terminated, then after allocating your block of memory, zero (0) all characters. As mentioned earlier, memset is available, but if you choose calloc instead of malloc it will zero the memory for you. However, on realloc the new space is NOT zero'ed either way, so calling memset is required regardless of what function originally allocated the block.

提示2 查看POSIX getline getline 将处理所需的分配/重新分配,只要被初始化为 NULL getline 还会返回实际读取的字符数,需要在 fgets之后调用 strlen 确定一样。

Tip2 Look at the POSIX getline. getline will handle the allocation/reallocation needed so long as line is initialized to NULL. getline also returns the number of characters actually read dispensing with the need to call strlen after fgets to determine the same.

如果您有其他问题,请告知我。

Let me know if you have additional questions.

这篇关于在C中从文件中读取一行,动态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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