【问题标题】:How to use fgets after using fgetc?使用 fgetc 后如何使用 fgets?
【发布时间】:2021-12-28 23:29:15
【问题描述】:

我正在尝试编写一个从文件中读取数据的特定程序,但我意识到当我使用 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,代码会打印文件内容。为什么会这样?

【问题讨论】:

  • 如果你循环直到到达 EOF,你希望之后能读到什么?
  • 旁白:fgetc(arq) 返回 257 个不同值中的 1 个。保存在char 会丢失一些东西。使用int enter
  • 非常感谢您的澄清。那么,如何重置呢?
  • 使用fseek() 回到开头。
  • 为什么需要第一个循环?如果要获取行数,只需计算您调用fgets() 的次数即可。

标签: c file fgets fgetc


【解决方案1】:

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

当您从文件中读取时,内部文件指针会随着您的读取而前进,因此每次后续读取都将返回文件中的下一个数据。当你读完时,所有后续的读取都将返回 EOF,因为没有什么要读取的了。

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

概要

 #include <stdio.h>

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

 long ftell(FILE *stream);

 void rewind(FILE *stream);

描述

fseek() 函数为 stream 指向的流设置文件位置指示符。 新位置(以字节为单位)是通过将偏移字节添加到位置来获得的 由哪里指定。如果 wherece 设置为 SEEK_SETSEEK_CURSEEK_END,则偏移量为 相对于文件开头、当前位置指示符或文件结尾,分别 慢慢地。成功调用 fseek() 函数会清除文件结束指示符 流并撤消 ungetc(3) 函数对同一流的任何影响。

ftell() 函数获取文件位置指示器的当前值 流指向的流。

rewind() 函数为 stream 指向的流设置文件位置指示符 到文件的开头。相当于:

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

除了流的错误指示符也被清除(参见 clearerr(3))。

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

【讨论】:

    猜你喜欢
    • 2019-04-23
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 2020-11-24
    相关资源
    最近更新 更多