如何用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; }
关键逻辑解释
- 索引计数:用
current_index变量跟踪当前字符的索引,比依赖ftell()更可靠(避免文本文件中换行符的字节偏移干扰)。 - 位置保存:当遍历到索引4时,先用
ftell()记录当前文件指针的位置(此时指针已经指向索引5,因为getc()读完字符后会自动后移)。 - 指针回退:用
fseek(fp, current_index, SEEK_SET)将指针移回索引4的起始位置,确保d从目标位置开始遍历。 - 恢复指针:
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
相关产品推荐
相关产品推荐

