从C中的文件读取长行时处理内存 [英] Handle memory while reading long lines from a file in 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屋!