You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用while((c = getc(file)) != EOF)实现文件两次无干扰遍历?

实现文件双遍历且互不干扰的解决方案

这个需求核心是处理文件指针的位置保存与恢复——因为getc()每次调用都会移动文件指针,直接嵌套遍历会打乱第一个循环的进度。下面是完全符合你需求的C语言实现:

代码示例

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

int main() {
    FILE *fp = fopen("test.txt", "r");
    if (fp == NULL) {
        perror("Failed to open file");
        return EXIT_FAILURE;
    }

    int c, d;
    long save_pos; // 用于保存文件指针位置
    int current_index = 0; // 记录当前字符的索引

    // 第一个遍历循环(变量c)
    while ((c = getc(fp)) != EOF) {
        printf("c: %c (当前索引: %d)\n", c, current_index);

        // 当c处于索引4位置时,启动第二个遍历
        if (current_index == 4) {
            // 保存当前文件指针位置:因为getc读完索引4的字符后,指针已经到了索引5
            save_pos = ftell(fp);
            if (save_pos == -1) {
                perror("Failed to get file position");
                fclose(fp);
                return EXIT_FAILURE;
            }

            // 将文件指针移回索引4的位置,让d从这里开始遍历
            if (fseek(fp, current_index, SEEK_SET) != 0) {
                perror("Failed to seek file");
                fclose(fp);
                return EXIT_FAILURE;
            }

            printf("\n=== 启动d的遍历 ===\n");
            // 第二个遍历循环(变量d)
            while ((d = getc(fp)) != EOF) {
                printf("d: %c\n", d);
            }

            // 恢复文件指针到之前保存的位置,让c继续遍历
            if (fseek(fp, save_pos, SEEK_SET) != 0) {
                perror("Failed to restore file position");
                fclose(fp);
                return EXIT_FAILURE;
            }
            printf("=== d的遍历结束,c继续 ===\n\n");
        }

        current_index++;
    }

    fclose(fp);
    return EXIT_SUCCESS;
}

关键逻辑解释

  1. 索引计数:用current_index变量跟踪当前字符的索引,比依赖ftell()更可靠(避免文本文件中换行符的字节偏移干扰)。
  2. 位置保存:当遍历到索引4时,先用ftell()记录当前文件指针的位置(此时指针已经指向索引5,因为getc()读完字符后会自动后移)。
  3. 指针回退:用fseek(fp, current_index, SEEK_SET)将指针移回索引4的起始位置,确保d从目标位置开始遍历。
  4. 恢复指针:d遍历完成后,用fseek()将指针恢复到之前保存的位置,这样c的遍历就能从索引5继续,完全不受d的影响。

测试结果(针对你的示例文件内容"1234a456468")

运行后会输出:

c: 1 (当前索引: 0)
c: 2 (当前索引: 1)
c: 3 (当前索引: 2)
c: 4 (当前索引: 3)
c: a (当前索引: 4)

=== 启动d的遍历 ===
d: a
d: 4
d: 5
d: 6
d: 4
d: 6
d: 8
=== d的遍历结束,c继续 ===

c: 4 (当前索引: 5)
c: 5 (当前索引: 6)
c: 6 (当前索引: 7)
c: 4 (当前索引: 8)
c: 6 (当前索引: 9)
c: 8 (当前索引: 10)

内容的提问来源于stack exchange,提问作者e t

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:28:15