为什么这个程序一次又一次不显示第一行?

发布于 2024-08-17 07:35:12 字数 945 浏览 4 评论 0原文

#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

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

#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;
}

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

满身野味 2024-08-24 07:35:12

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. 您正在为每个字符重新分配内存,这可能是一项昂贵的操作。

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.
辞慾 2024-08-24 07:35:12

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

啊,我理解你的困惑。

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

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

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.

浪推晚风 2024-08-24 07:35:12

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

当它前进到换行符之后,它自然地移动到下一个字符,即下一行的开头。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文