C语言练习求助:提取文件每行第m至n列内容输出至stdout
解决C语言逐行提取第m至n列的问题
嘿,我之前刚做过类似的C语言练习题,踩过几个关键的坑,给你捋捋怎么搞定这个问题!
首先,咱们得先明确问题核心:逐行处理文件内容,对每一行来说,只输出第m到第n个字符(题目里的“列”一般是从1开始计数的,而C语言字符串索引是从0开始,这很容易搞混),处理完一行后要换行,下一行重新从第m列开始判断。你遇到的换行和列计数错误,大概率是没处理好换行符的重置逻辑,或者列数的起始计数搞错了。
常见错误原因
- 列计数没在换行时重置:比如一直在累加列号,换行后没有把列数重新设为1,导致下一行的列号接着上一行的数继续算,自然没法从第m列开始。
- 混淆1-based和0-based计数:题目说的“第m列”是从1开始数,但C里读取字符时如果从0开始计数,就会少读或多输出字符,导致结果不对。
- 没正确处理换行符:比如读取到换行符时没输出换行,或者把换行符当成普通字符计入列数,导致列数统计错误。
可运行的示例代码
我写了一个完整的示例,每一步都加了注释,你可以参考:
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { // 检查参数:需要传入文件名、m、n if (argc != 4) { fprintf(stderr, "用法: %s <文件名> <m> <n>\n", argv[0]); return 1; } // 解析m和n,转换为整数(默认是1-based的列号) int m = atoi(argv[2]); int n = atoi(argv[3]); if (m < 1 || n < m) { fprintf(stderr, "请确保m≥1且n≥m\n"); return 1; } // 打开文件 FILE *fp = fopen(argv[1], "r"); if (fp == NULL) { perror("打开文件失败"); return 1; } int col = 1; // 当前列号,从1开始计数 int c; // 逐字符读取文件 while ((c = fgetc(fp)) != EOF) { if (c == '\n') { // 遇到换行符,输出换行,重置列号 putchar('\n'); col = 1; } else { // 当前列在m到n之间,输出字符 if (col >= m && col <= n) { putchar(c); } // 列号加1 col++; } } // 处理文件最后一行没有换行的情况 if (col > 1) { putchar('\n'); } fclose(fp); return 0; }
代码关键部分解释
- 参数处理:通过命令行传入文件名、m、n,你也可以改成用
scanf从终端读入m和n再输入文件名,逻辑完全一致。 - 列号重置:每次遇到换行符
'\n',就输出换行并把col重置为1,确保下一行的列数从1开始重新计数。 - 字符输出逻辑:只有当前列号在m到n之间时,才输出该字符,其他字符直接跳过。
- 边界处理:如果文件最后一行没有换行符,循环结束后手动输出换行,避免内容挤在一起。
调试小技巧
如果你还是有问题,可以试试这些排查方法:
- 在循环里加一句
printf("当前列号: %d, 字符: %c\n", col, c);,打印每一步的列号和字符,看看计数是否正确。 - 测试简单输入:比如创建一个只有两行的文件,每行5个字符,设m=2、n=4,看看输出是不是每行的第2-4个字符,换行是否正确。
- 检查m和n的输入:用
printf("m: %d, n: %d\n", m, n);确认输入的数值没有被错误转换。
内容的提问来源于stack exchange,提问作者Areg Sarvazyan
相关产品推荐
相关产品推荐

