[英]Reading a Line From File using fgets
What should be incredible simple has me stumped. 让我感到难过的是简单的事情。 All I am doing is writing a getLine
method that should read a line into a buffer. 我正在做的是编写一个getLine
方法,该方法应将一行读入缓冲区。 I allocate memory to the buffer starting at 10 bytes
, then fgets
into a char array. 我从10 bytes
开始向缓冲区分配内存,然后将fgets
放入char数组。 The idea is that I attempt this over and over, doubling the size of the buffer, until it gets the whole line. 我的想法是,我一遍又一遍地尝试,使缓冲区的大小加倍,直到获得整行。 However what I seem to be observing is that it reads a portion of the line, and then on the next attempt continues where it ran out of room on the last attempt, so it gives the last part of the line. 但是,我似乎正在观察的是,它读取了行的一部分,然后在下一次尝试时继续进行,直到上一次尝试它在空间不足的地方,所以它给出了行的最后一部分。 Any insight it to what is wrong, I expect with my realloc
memory to the buffer, would be much appreciated. 任何了解它什么是错的,我跟我的预期realloc
内存缓冲区,将不胜感激。
char * mygetline( char **buffer, FILE * infile )
{
int buffSiz = 10;
*buffer = calloc( buffSiz, 1 );
do
{
char * result = fgets(*buffer, sizeof *buffer ,infile);
if(result == NULL)
{
free(buffer);
return NULL;
}
if(strchr(*buffer, '\n'))
return *buffer;
else
{
char *newBuf;
buffSiz = buffSiz*2;
newBuf = realloc(NULL, buffSiz);
char *buffer = newBuf;
printf("%d", buffSiz);
printf("%s", *buffer);
}
} while (1); // INFINITE LOOP - WE ONLY GET OUT BY RETURNING FROM WITHIN
There are multiple flaws: 有多个缺陷:
sizeof *buffer
doesn't do what you want since it's a pointer. sizeof *buffer
不能执行您想要的操作,因为它是一个指针。 You should use buffSiz
instead 您应该改用buffSiz
char *buffer = newBuf;
you're assigning the new memory to a local variable, ie a variable that disappears when the else
is exited 您正在将新内存分配给局部变量,即,一个变量在退出else
时消失
you're not passing your buffer to realloc
, you're always passing NULL
您没有将缓冲区传递给realloc
,而是始终传递NULL
you're not checking the return of realloc
您没有检查realloc
的返回
As a shameless self-promotion, here's a function I posted in another answer . 作为无耻的自我推广, 这是我在另一个答案中发布的功能 。
That's how the file functions works. 这就是文件功能的工作方式。 You have to get the file position at the start, then reset the position every time you attempt a new read. 您必须从头开始获取文件位置,然后在每次尝试进行新的读取时重置该位置。
You can get the current position with the ftell
function, and then set the position with the fseek
function. 您可以使用ftell
函数获取当前位置,然后使用fseek
函数设置位置。
Instead of doing that (getting position and constant repositioning the file position), why not use the fact that realloc
reallocates the passed in buffer and keeps the contents together with the fact that the read functions reads the next part? 而不是这样做(获取位置并恒定地重新定位文件位置),为什么不使用realloc
重新分配传入的缓冲区并保留内容以及read函数读取下一部分的事实呢? In that case you need to have a pointer to where to read next, and if no newline then just reallocate and advance the pointer? 在这种情况下,您需要有一个指向下一个要读取的位置的指针,如果没有换行符,那么只需重新分配并前进该指针?
Something like this: 像这样:
char *readpos = *buffer;
size_t readsize = bufSize;
while (1)
{
char *p = fgets(readpos, readsize, infile);
if (!p)
break; /* Error */
/* Search from the end, as there's where the newline should be */
if (strrchr(p, '\n') != NULL)
return *buffer; /* Found the newline */
/* Need to allocate more memory */
bufSize += bufsize;
*buffer = realloc(*buffer, bufSize);
/* Set the pointer to next position to read into */
readpos = *buffer + strlen(buffer);
/* Loop takes case of trying again */
}
Note: The above code was written in the browser, not tested, and might need some tuning to make it work properly. 注意:上面的代码是在浏览器中编写的,未经测试,可能需要进行一些调整才能使其正常运行。
realloc期望将需要重新分配的缓冲区作为其第一个参数。
realloc(*buffer, buffSiz);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.