开发者

Why is this program not showing the first line again and again?

#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;
    }
    ret开发者_如何学运维urn 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;
}

If the contents of testFile is:-

abc
def
ghi

The three printf statements should show "abc" three times.. But the output is:-

abc
def
ghi

I know I am wrong in the concept somewhere. Pls help.


Usage of realloc() is incorrect.

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

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

Because line is passed by value, it's not changed. The actual re-allocated memory is in the return value. Therefore line remains the same over and over again, and you are seeing the same line over and over again. Edit: just realized that's even though it's a bug, it's not what would cause repeating lines. Other points are still valid.

What's worse:

  1. You have a memory leak by losing the newly re-allocated pointer every time.
  2. You are potentially accessing freed memory, because old line value may become invalid after reallocation, if it was reallocated in a different part of the heap.
  3. You are re-allocating memory every character, which is potentially an expensive operation.


But I am passing file pointer by value. So i should get output "abc" again and again

Ah, I understand your confusion.

A file pointer only points to the actual file structure. State such as the current offset are not part of the pointer but are part of the internal structure.

Another way to think about this is that the actual object representing the file is FILE. To get pass-by-reference semantics, you pass a pointer to the object. Since you are passing by reference, each line picks up where the last one left off.


fgetc() advances the file pointer (which is "where the next character to be read is located"). That's how you're able to call it in a loop and read a whole line of characters.

After it advances past the newline character, it naturally moves on to the next character, which is the beginning of the next line.

You could modify the file pointer with the fseek() function. For example, calling fseek(inFile, 0, SEEK_SET) would reset it to the beginning of the file, causing the next fgetc() call to start over from the first character of the file.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜