使用fgetc后如何使用fgets?

How to use fgets after using fgetc?

我正在尝试编写一个从文件中读取数据的特定程序,但我意识到当我使用 fgetc 读取文件时,如果我稍后使用 fgets,它没有任何输出。

例如,这段代码:

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

int main() {
    FILE * arq = fopen("arquivo.txt", "r");
    char enter = fgetc(arq);
    int line_count = 1;
    
    while(enter != EOF) {
        if (enter == '\n') line_count++;
        enter = fgetc(arq);
    }

    printf("%d", line_count);
    char str[128];

    while(fgets(str, 128, arq)) printf("%s", str);
}

第二个 while 不打印任何内容,但如果我删除第一个 while,代码会打印文件内容。为什么会这样?

TLDR:rewind(arq); 就是你想要的

当您从文件中读取时,内部文件指针会随着您的读取而前进,因此每次后续读取都会 return 文件中的下一个数据。当您读到最后时,所有后续读取都将 return EOF,因为没有更多内容可读。

您可以使用 fseekftell 函数操作内部文件指针。 fseek 允许您将内部文件指针设置为文件中相对于开头、结尾或当前位置的任意点。 ftell 会告诉您当前位置。这使您可以轻松记住文件中的任何位置并稍后返回。

SYNOPSIS

 #include <stdio.h>

 int fseek(FILE *stream, long offset, int whence);

 long ftell(FILE *stream);

 void rewind(FILE *stream);

DESCRIPTION

The fseek() function sets the file position indicator for the stream pointed to by stream. The new position, measured in bytes, is obtained by adding offset bytes to the position specified by whence. If whence is set to SEEK_SET, SEEK_CUR, or SEEK_END, the offset is relative to the start of the file, the current position indicator, or end-of-file, respec‐ tively. A successful call to the fseek() function clears the end-of-file indicator for the stream and undoes any effects of the ungetc(3) function on the same stream.

The ftell() function obtains the current value of the file position indicator for the stream pointed to by stream.

The rewind() function sets the file position indicator for the stream pointed to by stream to the beginning of the file. It is equivalent to:

  (void) fseek(stream, 0L, SEEK_SET)

except that the error indicator for the stream is also cleared (see clearerr(3)).

这里需要注意的是,fseek 使用的偏移量和 ftell 使用的 returned 是字节偏移量,而不是字符偏移量。因此,当访问非二进制文件(任何未使用 fopen 的 "b" 修饰符打开的文件)时,偏移量可能与字符不完全对应。将由 ftell 编辑的偏移量 return 不加修改地传递回 fseek 以到达文件中的相同位置应该总是没问题的,但是尝试计算偏移量可能会很棘手。