如何修改C语言文件IO与数组读取代码以避免输出垃圾值?
问题分析与代码修改
原代码存在的问题
- 行索引未重置:变量
i在循环外定义,处理完第一行后,后续行的字符会从i的当前位置(而非下标0)开始存储,导致每行前半部分残留未初始化的垃圾值。 - 未处理文件提前结束的情况:文件仅有2行,但代码强制循环3次,第三行的数组完全未初始化,输出时会读取垃圾内存。
- 固定长度输出:输出时强制打印每行前10个字符,不管字符串实际长度,超出部分会访问未初始化的内存区域。
修改后的代码
#include <stdio.h> #define FILENAME "file.txt" #define MAXSIZE 128 int main(void) { setvbuf(stdout, NULL, _IONBF, 0); FILE *file = fopen(FILENAME, "r"); if (!file) { perror(FILENAME); return 1; } int ch; char array[3][MAXSIZE]; // 初始化数组为0,避免未初始化的垃圾值残留 for(int a=0; a < 3; a++) { for(size_t j=0; j < MAXSIZE; j++) { array[a][j] = '\0'; } } for(int a=0; a < 3; a++) { size_t i = 0; // 每处理一行就重置索引为0 while (i < MAXSIZE - 1 && ((ch = getc(file)) != EOF)) { if (ch == '\n') break; array[a][i++] = ch; } array[a][i] = '\0'; // 确保字符串以终止符结尾 // 读到文件末尾时,停止后续循环 if (ch == EOF) { break; } } fclose(file); // 按实际字符串长度输出,避免打印垃圾值 for(int a=0; a < 3; a++) { if (array[a][0] == '\0') { // 跳过未写入数据的行 break; } printf("%s\n", array[a]); // 如果需要固定打印前10个有效字符,可替换为以下代码: // for(size_t i=0; i < 10 && array[a][i] != '\0'; i++) { // printf("%c", array[a][i]); // } // printf("\n"); } return 0; }
关键修改说明
- 重置行索引:将
size_t i的定义移到外层循环内部,每处理一行前重置为0,确保每行字符都从数组下标0开始存储。 - 终止空循环:读取完一行后检查是否到达EOF,若已读完文件则跳出外层循环,避免处理无数据的行。
- 初始化数组:提前将数组所有元素设为
'\0',即使某行未被写入,也不会出现垃圾值。 - 按需输出:使用
printf("%s", array[a])自动识别字符串终止符停止打印,或循环时判断字符是否为终止符,只输出有效内容。
内容的提问来源于stack exchange,提问作者Rosaline
相关产品推荐
相关产品推荐

