C语言文件读取代码编译正常但无输出,请求错误排查
问题分析与修正方案
核心问题:无输出的直接原因
- 变量
fila初始化为0,且在整个文件读取过程中从未递增,导致打印循环for (i = 0; i < fila; i++)的条件始终不成立,完全不会执行打印逻辑。
其他严重错误(会导致程序崩溃或数据异常)
- 缺少必要头文件:使用
strtok、strcpy等字符串操作函数时,必须包含<string.h>头文件,否则编译器可能报错或触发未定义行为。 - 结构体成员类型不匹配:结构体中
nombre、prelaciones、siguientes被定义为二维字符数组,但你的文本文件中这些字段是单个字符串(如Informatica、TEC-100),直接用strcpy赋值给二维数组属于类型不兼容操作,会引发未定义行为。 - 未检查文件读取结束状态:原代码固定循环
MAX_FILAS次,当文件内容读完后,fgets会返回NULL,后续strtok也会得到NULL,此时访问campos[0]等元素会导致数组越界,引发程序崩溃或错误数据。 - 潜在的缓冲区溢出风险:直接使用
strcpy没有限制复制长度,若文件中字段长度超过结构体成员的数组大小,会导致缓冲区溢出。
修正后的代码
#include <stdio.h> #include <string.h> // 新增必要头文件 #define MAX_FILAS 100 #define MAX_COLUMNAS 100 #define MAX_CODIGO 10 #define MAX_NOMBRE 41 #define MAX_PRELACION 10 #define MAX_SIGUIENTE 10 struct carreras { char codigo[MAX_CODIGO]; char nombre[MAX_NOMBRE]; // 修改为一维数组,匹配文件单个字符串格式 char prelaciones[MAX_PRELACION]; // 修改为一维数组 char siguientes[MAX_SIGUIENTE]; // 修改为一维数组 char materias[41][10]; // 该字段未使用,可按需保留或删除 }; int main() { FILE *archivo; struct carreras carreras[MAX_FILAS]; int fila = 0; // 打开文件并检查是否成功 archivo = fopen("mododiablo.txt", "r"); if (archivo == NULL) { printf("No se pudo abrir el archivo.\n"); return 1; } // 读取文件内容,直到文件结束或达到最大行数 char linea[MAX_COLUMNAS]; while (fgets(linea, MAX_COLUMNAS, archivo) != NULL && fila < MAX_FILAS) { // 去除fgets读取到的换行符 linea[strcspn(linea, "\n")] = '\0'; // 分割行内字段 char *campos[4]; char *token = strtok(linea, ";"); int j = 0; while (token != NULL && j < 4) { // 限制字段数量,避免越界 campos[j++] = token; token = strtok(NULL, ";"); } // 确认读取到4个字段后再赋值 if (j == 4) { // 使用strncpy避免缓冲区溢出,手动添加字符串结束符 strncpy(carreras[fila].codigo, campos[0], MAX_CODIGO - 1); carreras[fila].codigo[MAX_CODIGO - 1] = '\0'; strncpy(carreras[fila].prelaciones, campos[1], MAX_PRELACION - 1); carreras[fila].prelaciones[MAX_PRELACION - 1] = '\0'; strncpy(carreras[fila].nombre, campos[2], MAX_NOMBRE - 1); carreras[fila].nombre[MAX_NOMBRE - 1] = '\0'; strncpy(carreras[fila].siguientes, campos[3], MAX_SIGUIENTE - 1); carreras[fila].siguientes[MAX_SIGUIENTE - 1] = '\0'; fila++; // 成功读取一行后递增行数计数 } } fclose(archivo); // 打印读取到的数据 for (int i = 0; i < fila; i++) { printf("Codigo: %s\n", carreras[i].codigo); printf("Nombre: %s\n", carreras[i].nombre); printf("Prelaciones: %s\n", carreras[i].prelaciones); printf("Siguientes: %s\n", carreras[i].siguientes); printf("------------------------\n"); } return 0; }
修正说明
- 补充
<string.h>头文件,解决字符串操作函数的编译依赖问题。 - 调整结构体成员类型为一维字符数组,匹配文件中单个字符串的格式,消除类型不兼容错误。
- 改用
while循环读取文件,同时递增fila变量,确保打印循环能正常遍历已读取的数据。 - 使用
strncpy替代strcpy,并手动添加字符串结束符,避免缓冲区溢出风险。 - 添加字段数量检查,防止因行格式错误导致的数组越界访问。
- 去除全局变量
i,改用局部变量,减少全局变量带来的潜在问题。
内容的提问来源于stack exchange,提问作者Javier Pacheco
相关产品推荐
相关产品推荐

