C语言存储多行文本到数组仅输出首个超80字符行问题求助
代码bug修复方案
你的程序仅输出第一条超过80字符的输入行,是三处明确的逻辑错误导致的:
- 输出缓冲区偏移量未初始化:
main函数中的outlen是栈上局部变量,不显式赋值为0的话,初始值是随机内存垃圾值,第一次调用append时写入位置完全不可控。 append函数索引逻辑错误:原实现用同一个下标i同时定位源数组from的读位置和目标数组to的写位置,但from存储的当前输入行永远从下标0开始,to的写入起始位置才是传入的偏移量i,共用索引会导致读取源字符串时直接跳过有效内容,访问到内存垃圾。append返回值错误:return i++是后置自增,返回的是自增前的下标值(也就是换行符所在位置),下一次追加内容时会直接从换行符位置覆盖写入,永远不会推进输出缓冲区的总长度。
另外原代码中printlines总输出缓冲区和单条输入行的大小都是1000,存储多条长输入行时会出现数组越界,需要放大缓冲区尺寸。
修正后完整代码
#include <stdio.h> #define MAXLINE 1000 /* 单条输入行最大长度 */ #define MINLENGTH 80 /* 触发输出的行最小长度 */ #define MAXOUTPUT 10000 /* 总输出缓冲区最大长度,避免存多行时越界 */ int getlone(char line[], int maxline); int append(char to[], char from[], int to_start); /* 读取所有输入行,EOF时一次性输出长度超过80字符的行 */ int main(){ int len; /* 当前输入行长度 */ int outlen = 0; /* 输出缓冲区已存内容的总长度,必须初始化为0 */ char line[MAXLINE]; /* 暂存单条输入行 */ char printlines[MAXOUTPUT]; /* 存储所有符合输出要求的行 */ while((len = getlone(line, MAXLINE)) > 0){ if (len > MINLENGTH){ outlen = append(printlines, line, outlen); } } printlines[outlen] = '\0'; printf("%s", printlines); return 0; } /* getlone: 读取一行输入到s数组,返回该行长度 */ int getlone(char s[], int lim){ int c, i; for(i=0; i < lim-1 && (c = getchar()) != EOF && c != '\n'; i++){ s[i] = c; } if (c == '\n') { s[i] = c; i++; } return i; } /* append: 将from存储的输入行追加到to数组末尾,返回追加后to数组的总长度 */ int append(char to[], char from[], int to_start){ int from_idx = 0; // 源字符串从下标0开始读,目标字符串从传入的偏移位置开始写 while((to[to_start] = from[from_idx]) != '\n'){ to_start++; from_idx++; } // 写完换行符后偏移量再进1,指向下一次可写入的空位置 to_start++; return to_start; }
使用说明
编译运行修正后的代码,可逐行输入内容,长度不足80的行会被直接丢弃,符合长度要求的行会暂存到内存缓冲区。输入EOF时(Windows系统按Ctrl+Z后回车,Linux/macOS系统按Ctrl+D),所有符合要求的行会一次性打印输出,和K&R书中示例的行为完全一致。
内容的提问来源于stack exchange,提问作者Cetaphil
相关产品推荐
相关产品推荐

