C语言剧场座位管理项目:guarda_estado_sala函数无响应求助
剧场座位管理项目文件写入问题排查
问题描述
我正在开发一个大学课程的剧场座位管理项目,需要将剧场座位状态写入文件。但调用guarda_estado_sala()函数时完全无反应,即便在函数内添加printf语句也无效。该函数应将指针变量sala中存储的客户ID写入文件,恳请协助排查问题原因。
相关代码
库文件代码
//Cuerpo biblioteca #include <stdlib.h> #include <stdio.h> //cabeceras archivos #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> //para close int* sala; int aforo; void crea_sala(int capacidad){ sala = (int*) malloc(capacidad* sizeof(int)); aforo = capacidad; for(int i = 0; i<capacidad; i++){ *(sala+i) = -1; } } int reserva_asiento(int id){ for(int i = 1; i <= aforo; i++){ if(*(sala+i-1) ==id){ return -2; } } for(int i = 1; i <= aforo; i++){ if(*(sala+i-1) ==-1){ *(sala+i-1) = id; return i; } } return -1; } int libera_asiento(int asiento){ int devuelve = *(sala+asiento-1); *(sala+asiento-1) = -1; return devuelve; } int estado_asiento(int asiento){ if(*(sala+asiento-1) == -1){ return 0; }else if(*(sala+asiento-1) > 0){ return *(sala+asiento-1); }else{ return -1; } } int asientos_libres(){ int contador = 0; for(int i = 1; i<=aforo; i++){ if(estado_asiento(i) == 0){ contador++; } } return contador; } int asientos_ocupados(){ return aforo-asientos_libres(); } int capacidad(){ return aforo; } void elimina_sala(){ free(sala); } int encuentra_asiento(int id){ for(int i = 0; i<aforo; i++){ if(estado_asiento(i) == id){ return i+1; } } return -1; } // THIS IS THE FUNCTION: int guarda_estado_sala(const char* ruta_fichero){ int fd = creat(ruta_fichero, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); for(int i=0; i<aforo; i++){ write(fd, (char) *(sala+i), sizeof(char)); } close(fd); return 0; }
主函数代码
#include <stdio.h> #include <stdlib.h> #include "../cabeceras/sala.h" void main(){ crea_sala(10); reserva_asiento(10); guarda_estado_sala("saladeprueba.txt"); elimina_sala(); }
问题原因及修复方案
1. 文件创建未做错误检查
creat函数在创建文件失败时会返回-1(比如无权限、路径不存在等),但原代码没有检查返回值,后续的write和close操作在fd=-1时会直接失败,却无法被察觉。
2. write函数参数错误
原代码中write(fd, (char) *(sala+i), sizeof(char))存在两个问题:
- 第二个参数需要是指向数据的指针,但你把
int类型的sala[i]强转成char后直接传递,相当于传递了一个数值而非指针,这会导致非法内存访问。 - 每个座位ID是
int类型(通常占4字节),但你只写入1字节,会丢失数据。
3. 可选:数据格式选择
如果需要写入文本格式的ID(方便查看),建议使用标准IO函数(如fopen、fprintf)而非系统调用;如果需要二进制存储,要保证写入完整的int数据。
修复后的函数示例
二进制存储版本(保留系统调用)
int guarda_estado_sala(const char* ruta_fichero){ int fd = creat(ruta_fichero, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd == -1) { // 检查文件创建是否成功 perror("Error al crear el fichero"); return -1; } // 一次性写入整个数组,效率更高 ssize_t bytes_escritos = write(fd, sala, aforo * sizeof(int)); if (bytes_escritos != aforo * sizeof(int)) { perror("Error al escribir en el fichero"); close(fd); return -1; } close(fd); return 0; }
文本存储版本(更易读取)
int guarda_estado_sala(const char* ruta_fichero){ FILE* fichero = fopen(ruta_fichero, "w"); if (fichero == NULL) { perror("Error al abrir el fichero"); return -1; } for(int i=0; i<aforo; i++){ fprintf(fichero, "%d\n", sala[i]); // 每个ID单独一行 } fclose(fichero); return 0; }
其他次要问题修复
- 主函数
void main()不符合C标准,应改为int main()并添加return 0;。 encuentra_asiento函数存在数组越界:循环中调用estado_asiento(i)(i从0开始),但estado_asiento的参数是从1开始的座位号,会访问sala[-1]。修复后直接访问数组:
int encuentra_asiento(int id){ for(int i = 0; i<aforo; i++){ if(sala[i] == id){ return i+1; } } return -1; }
内容的提问来源于stack exchange,提问作者Nicolás Marcelo
相关产品推荐
相关产品推荐

