You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:12:54