C语言读取stdin行到指针数组仅打印首行如何解决?
问题原因分析
你的代码只输出第一行是由两个逻辑错误共同导致的:
- 第一个错误:
readlines函数的for循环增量逻辑错误
当你匹配到换行符、将c_ptr切换为下一行缓冲区的首地址后,for循环会自动执行一次++c_ptr增量操作,导致下一行的第一个字符被写入缓冲区的第二个位置,缓冲区首地址留存的是malloc分配的未初始化垃圾值,如果该值恰好为\0,该行就会变成空字符串,无法正常打印。 - 第二个错误:最后一行无换行符时不会被计数
如果输入的最后一行没有以换行符结尾,循环遇到EOF直接退出,这部分内容不会被计入num统计的行数,导致返回的行数比实际行数少1。
另外补充一个隐性问题:getchar()返回值为int类型,直接赋值给char类型指针指向的空间,遇到EOF(值为-1)时如果系统的char是无符号类型,会出现判断逻辑错误。
修复后的代码
#include <stdlib.h> #include <stdio.h> #include <string.h> #define MAXLINES 5000 char *lineptr[MAXLINES]; int readlines(char *[], int); void writelines(char *[], int); int main(int argc, char *argv[]) { int i, nlines; for (i = 0; i < MAXLINES; ++i) { lineptr[i] = malloc(MAXLINES * sizeof(**lineptr)); } nlines = readlines(lineptr, MAXLINES); writelines(lineptr, nlines); return 0; } int readlines(char *lineptr[], int nlines) { int num = 0; char *c_ptr = lineptr[num]; int ch; while ((ch = getchar()) != EOF) { *c_ptr = ch; if (ch == '\n') { *c_ptr = '\0'; num++; if (num >= nlines) { return num; } // 切换到下一行缓冲区首地址 c_ptr = lineptr[num]; // 跳过c_ptr自增,下一个字符直接写入新行首 continue; } c_ptr++; } // 处理最后一行无换行符的情况 *c_ptr = '\0'; num++; return num; } void writelines(char *lineptr[], int nlines) { while (nlines--) { printf("%s\n", *lineptr++); } }
内容的提问来源于stack exchange,提问作者S.Sot
相关产品推荐
相关产品推荐

