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

char *readLine(FILE *inFile)  //Simply reads line in a text file till "\n"
{
    char *line = realloc(NULL, 1);
    char c;
    int i=0;
    while (!feof(inFile))
    {
        c = fgetc(inFile);
        if (ferror(inFile)) printf("Error reading");
        if (c == 10)
            {
                realloc(line,i+1);
                line[i]= 10;
                break;
            }
        realloc(line, i+1);
        line[i++] = c;
    }
    return line;
}

int main(int argc,char **argv)
{
    FILE *inFile;
    inFile = fopen("testFile","r");
    printf("%s",readLine(inFile));
    printf("%s",readLine(inFile));
    printf("%s",readLine(inFile));
    return 0;
}

如果 testFile 的内容是:-

abc
def
ghi

三个 printf 语句应该显示“abc”三次。但输出是:-

abc
def
ghi

我知道我在某个地方的概念是错误的。请帮忙。

4

3 回答 3

6

的用法realloc()不正确。

realloc(line,i+1); // wrong

// OK
void *new_line = realloc(line,i+1);
if (!new_line)
{
    free(line);
    return NULL;
}
line = new_line;

因为line是按值传递的,所以没有改变。实际重新分配的内存在返回值中。因此line一遍又一遍地保持不变,而你一遍又一遍地看到同一条线。 编辑:刚刚意识到即使它是一个错误,也不会导致重复行。其他点仍然有效。

更糟糕的是:

  1. 每次丢失新分配的指针都会导致内存泄漏。
  2. 您可能正在访问已释放的内存,因为如果旧line值在堆的不同部分重新分配,则在重新分配后可能会变得无效。
  3. 您正在为每个字符重新分配内存,这可能是一项昂贵的操作。
于 2010-01-10T07:41:55.657 回答
4

fgetc()推进文件指针(这是“要读取的下一个字符所在的位置”)。这就是您能够在循环中调用它并读取整行字符的方式。

在它超过换行符之后,它自然地移动到下一个字符,即下一行的开头。

fseek()您可以使用该函数修改文件指针。例如,调用fseek(inFile, 0, SEEK_SET)会将其重置为文件的开头,从而导致下一次fgetc()调用从文件的第一个字符重新开始。

于 2010-01-10T07:48:48.357 回答
4

但我按值传递文件指针。所以我应该一次又一次地得到输出“abc”

啊,我理解你的困惑。

文件指针仅指向实际的文件结构。当前偏移量等状态不是指针的一部分,而是内部结构的一部分。

另一种思考方式是表示文件的实际对象是 FILE。要获得按引用传递的语义,您需要传递一个指向对象的指针。由于您是通过引用传递的,因此每一行都会从最后一行停止的地方开始。

于 2010-01-10T08:12:24.263 回答