从C中的文件读取长行时处理内存 [英] Handle memory while reading long lines from a file in C

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

问题描述

首先,我知道这个问题非常接近

First of all, I know this question is very close to this topic, but the question was so poorly worded that I am not even sure it is a duplicate plus no code were shown so I thought it deserved to be asked properly.

我正在尝试逐行读取文件,我需要特别在variable中存储一行.我设法使用fgets轻松地做到了这一点,尽管如此,要读取的行的大小和文件中的行数 仍然未知.
我需要一种方法来适当地将内存分配给variable,无论行的大小如何, 使用C而不是C ++ .

I am trying to read a file line by line and I need to store a line in particular in a variable. I have managed to do so quite easily using fgets, nevertheless the size of the lines to be read and the number of lines in the file remain unknown.
I need a way to properly allocate memory to the variable whatever the size of the line might be, using C and not C++.

到目前为止,我的代码如下:

So far my code looks like that :

allowedMemory = malloc(sizeof(char[1501])); // Checks if enough memory
if (NULL == allowedMemory)
{
    fprintf(stderr, "Not enough memory. \n");
    exit(1);
}
else
    char* res;
    res = allowedMemory;
while(fgets(res, 1500, file)) // Iterate until end of file
{
    if (res == theLineIWant) // Using strcmp instead of ==
        return res;
}

此代码的问题在于它根本无法适应.我正在寻找一种将足够的内存分配给res的方法,这样我就不会错过line中的任何数据.

The problem of this code is that it is not adaptable at all. I am looking for a way to allocate just enough memory to res so that I don't miss any data in line.

我在想类似的东西:

while ( lineContainingKChar != LineContainingK+1Char) // meaning that the line has not been fully read
// And using strcmp instead of ==
  realloc(lineContainingKChar, K + 100) // Adding memory

但是我需要遍历两个FILE对象以填充这些效率不高的变量. 关于如何实施此解决方案或以更简单的方式建议如何解决方案的任何提示,将不胜感激.

But I would need to iterate through two FILE object in order to fill these variables which would not be very efficient. Any hints about how to implement this solution or advise about how to do it in a easier way would be appreciated.

似乎使用getline()是最好的方法,因为此函数自行分配所需的内存,并在需要时释放它.尽管如此,我不认为它是100%可移植的,因为尽管包含了<stdio.h>,但我仍然无法使用它.由于我的问题通常位于键盘和计算机之间,因此有待验证.在此之前,我仍然对不使用符合POSIX的C的解决方案持开放态度.

EDIT : Seems like using getline() is the best way to do so because this function allocates the memory needed by itself and free it when needed. Nevertheless I don't think that it is 100% portable since I still can't use it though I have included <stdio.h>. To be verified though, since my issues are often situated between keyboard and computer. Until then I am still open to a solution which would not use POSIX-compliant C.

推荐答案

getline() 似乎完全可以满足您的要求:

getline() appears to do exactly what you want:

描述

DESCRIPTION

getdelim()函数应从流中读取,直到遇到 匹配分隔符的字符.

The getdelim() function shall read from stream until it encounters a character matching the delimiter character.

...

getline()功能应等同于getdelim() delimiter字符等于<newline>的函数 字符.

The getline() function shall be equivalent to the getdelim() function with the delimiter character equal to the <newline> character.

...

示例

EXAMPLES

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


int main(void)
{
    FILE *fp;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    fp = fopen("/etc/motd", "r");
    if (fp == NULL)
        exit(1);
    while ((read = getline(&line, &len, fp)) != -1) {
        printf("Retrieved line of length %zu :\n", read);
        printf("%s", line);
    }
    if (ferror(fp)) {
        /* handle error */
    }
    free(line);
    fclose(fp);
    return 0;
}

并且按照 Linux手册页:

说明

getline()从流中读取整行,并存储 包含文本到*lineptr的缓冲区.缓冲区为空- 终止并包含换行符(如果找到的话).

getline() reads an entire line from stream, storing the address of the buffer containing the text into *lineptr. The buffer is null- terminated and includes the newline character, if one was found.

如果在呼叫前将*lineptr设置为NULL并且*n设置为0,则 getline()将分配用于存储行的缓冲区.这个缓冲区 即使getline()失败,也应由用户程序释放.

If *lineptr is set to NULL and *n is set 0 before the call, then getline() will allocate a buffer for storing the line. This buffer should be freed by the user program even if getline() failed.

或者,在调用getline()之前,*lineptr可以包含一个 指向malloc(3)分配的缓冲区*n字节大小的指针.如果 缓冲区的大小不足以容纳该行,getline()调整其大小 使用realloc(3),根据需要更新*lineptr*n.

Alternatively, before calling getline(), *lineptr can contain a pointer to a malloc(3)-allocated buffer *n bytes in size. If the buffer is not large enough to hold the line, getline() resizes it with realloc(3), updating *lineptr and *n as necessary.

无论哪种情况,在成功呼叫后,*lineptr*n都将是 已更新以分别反映缓冲区地址和分配的大小.

In either case, on a successful call, *lineptr and *n will be updated to reflect the buffer address and allocated size respectively.

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

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