#include #include #include #include // 1. NÚCLEO DE OBJETOS: ESTRUCTURAS AUTOREFERENCIABLES EN C typedef struct NodoSesion { int FunIdSesion; char FunUsuario[100]; struct NodoSesion* FunSiguiente; } NodoSesion; typedef struct NodoTurno { int FunNumTurno; char FunMotivo[100]; struct NodoTurno* FunSiguiente; } NodoTurno; // 2. ORQUESTADOR CENTRAL DEL ENTORNO static NodoSesion* inicioSesiones = NULL; static NodoTurno* frenteCola = NULL; static NodoTurno* finalCola = NULL; static int funContadorSesionesDia = 0; static int funContadorTurnosDia = 0; // Declaraciones de funciones void FunIniciarSesion(const char* usuario); void FunEncolarTurno(const char* motivo); void FunDespacharTurno(void); void FunEscribirBitacora(const char* textoLog); void FunSincronizarColaDisco(void); void FunRecuperarColaDisco(void); void FunConsultarBitacora(void); void FunLiberarMemoria(void); int main(void) { int opcion = 0; FunRecuperarColaDisco(); // Carga automática de inicio do { printf("\n=== SISTEMA INTEGRADO PAD-BIENESTAR (C VERSION) ===\n"); printf("1. Registrar Sesion Activa\n2. Despachar Siguiente Turno\n3. Consultar Bitacora.txt\n4. Salir\n"); printf("\nC:\\PAD_Bienestar\\Estructuras> seleccione_opcion: "); char entrada[100]; if (fgets(entrada, sizeof(entrada), stdin) == NULL) { continue; } if (sscanf(entrada, "%d", &opcion) != 1) { printf("\n[MANEJADOR DE ERRORES] Error: Entrada invalida.\n\n"); continue; } switch (opcion) { case 1: { printf("\nNombre del Beneficiario: "); char nombre[100]; if (fgets(nombre, sizeof(nombre), stdin) != NULL) { // Eliminar salto de línea nombre[strcspn(nombre, "\r\n")] = '\0'; if (strlen(nombre) == 0) { printf("[MANEJADOR DE ERRORES] Nombre vacio.\n\n"); } else { FunIniciarSesion(nombre); } } break; } case 2: FunDespacharTurno(); break; case 3: FunConsultarBitacora(); break; case 4: { time_t t = time(NULL); struct tm* tm_info = localtime(&t); char fecha[20]; strftime(fecha, sizeof(fecha), "%Y-%m-%d %H:%M:%S", tm_info); char logTexto[256]; snprintf(logTexto, sizeof(logTexto), "SYS_SHUTDOWN -> [%s] RESUMEN JORNADA: %d Sesiones | %d Turnos Emitidos", fecha, funContadorSesionesDia, funContadorTurnosDia); FunEscribirBitacora(logTexto); printf("\n--> [DISK] Resumen inyectado en bitacora.txt.\n--> [STATUS] Ecosistema cerrado de forma segura.\n"); break; } default: printf("\n[MANEJADOR DE ERRORES] Error: Comando no reconocido. Ingrese de 1 a 4.\n\n"); break; } } while (opcion != 4); FunLiberarMemoria(); // Liberación completa de RAM antes de salir return 0; } void FunIniciarSesion(const char* usuario) { NodoSesion* nuevo = (NodoSesion*)malloc(sizeof(NodoSesion)); if (nuevo == NULL) { printf("\n[MANEJADOR DE ERRORES] Runtime Error: Sin memoria para asignar sesion.\n"); return; } nuevo->FunIdSesion = ++funContadorSesionesDia; strncpy(nuevo->FunUsuario, usuario, sizeof(nuevo->FunUsuario) - 1); nuevo->FunUsuario[sizeof(nuevo->FunUsuario) - 1] = '\0'; nuevo->FunSiguiente = inicioSesiones; inicioSesiones = nuevo; FunEncolarTurno("Atencion General PAD-Bienestar"); FunSincronizarColaDisco(); // Obtener marca de tiempo actual time_t t = time(NULL); struct tm* tm_info = localtime(&t); char fecha[20]; strftime(fecha, sizeof(fecha), "%Y-%m-%d %H:%M:%S", tm_info); char logTexto[256]; snprintf(logTexto, sizeof(logTexto), "REG_SESSION -> [%s] ID_SESION: %d | USUARIO: %s | TURNO: #%d", fecha, funContadorSesionesDia, usuario, funContadorTurnosDia); FunEscribirBitacora(logTexto); printf("\n>> [OK] Malloc completado. Nodo asignado con ID: %d\n", funContadorSesionesDia); printf(">> [AUTOMATIZACION] Puntero encolado. Turno emitido: #%d\n", funContadorTurnosDia); } void FunEncolarTurno(const char* motivo) { NodoTurno* nuevo = (NodoTurno*)malloc(sizeof(NodoTurno)); if (nuevo == NULL) { printf("\n[MANEJADOR DE ERRORES] Runtime Error: Sin memoria para encolar turno.\n"); return; } nuevo->FunNumTurno = ++funContadorTurnosDia; strncpy(nuevo->FunMotivo, motivo, sizeof(nuevo->FunMotivo) - 1); nuevo->FunMotivo[sizeof(nuevo->FunMotivo) - 1] = '\0'; nuevo->FunSiguiente = NULL; if (frenteCola == NULL) { frenteCola = nuevo; } else { finalCola->FunSiguiente = nuevo; } finalCola = nuevo; } void FunDespacharTurno(void) { if (frenteCola == NULL) { printf("\n[MANEJADOR DE ERRORES] Runtime Error: Cola vacia (Underflow).\n\n"); return; } NodoTurno* temp = frenteCola; frenteCola = frenteCola->FunSiguiente; if (frenteCola == NULL) { finalCola = NULL; } FunSincronizarColaDisco(); // Obtener marca de tiempo actual time_t t = time(NULL); struct tm* tm_info = localtime(&t); char fecha[20]; strftime(fecha, sizeof(fecha), "%Y-%m-%d %H:%M:%S", tm_info); char logTexto[256]; snprintf(logTexto, sizeof(logTexto), "FREE_TURNO -> [%s] DESPACHADO: Turno #%d | STATUS: Atendido", fecha, temp->FunNumTurno); FunEscribirBitacora(logTexto); printf("\n>> Atendiendo Turno #%d. Nodo destruido con free(temp).\n\n", temp->FunNumTurno); free(temp); } void FunEscribirBitacora(const char* textoLog) { FILE* fp = fopen("bitacora.txt", "a"); if (fp != NULL) { fprintf(fp, "%s\n", textoLog); fclose(fp); } } void FunSincronizarColaDisco(void) { FILE* fp = fopen("cola_respaldo.txt", "w"); if (fp != NULL) { NodoTurno* aux = frenteCola; while (aux != NULL) { fprintf(fp, "%d|%s\n", aux->FunNumTurno, aux->FunMotivo); aux = aux->FunSiguiente; } fclose(fp); } } void FunRecuperarColaDisco(void) { FILE* fp = fopen("cola_respaldo.txt", "r"); if (fp == NULL) return; char linea[256]; while (fgets(linea, sizeof(linea), fp) != NULL) { // Eliminar saltos de línea linea[strcspn(linea, "\r\n")] = '\0'; if (strlen(linea) == 0) continue; char* token_id = strtok(linea, "|"); char* token_motivo = strtok(NULL, "|"); if (token_id != NULL && token_motivo != NULL) { int id = atoi(token_id); NodoTurno* nuevo = (NodoTurno*)malloc(sizeof(NodoTurno)); if (nuevo != NULL) { nuevo->FunNumTurno = id; strncpy(nuevo->FunMotivo, token_motivo, sizeof(nuevo->FunMotivo) - 1); nuevo->FunMotivo[sizeof(nuevo->FunMotivo) - 1] = '\0'; nuevo->FunSiguiente = NULL; if (frenteCola == NULL) { frenteCola = nuevo; } else { finalCola->FunSiguiente = nuevo; } finalCola = nuevo; funContadorTurnosDia = id; funContadorSesionesDia = id; } } } fclose(fp); } void FunConsultarBitacora(void) { FILE* fp = fopen("bitacora.txt", "r"); if (fp == NULL) { printf("\n--> [ALERTA DISCO] El archivo bitacora.txt no existe.\n\n"); return; } printf("\n-------------------------------------------------------------\n"); printf(" CONTENIDO PERSISTENTE DE BITACORA.TXT (HISTORIAL DE EVENTOS) \n"); printf("-------------------------------------------------------------\n"); char c; while ((c = fgetc(fp)) != EOF) { putchar(c); } printf("-------------------------------------------------------------\n"); fclose(fp); } void FunLiberarMemoria(void) { // Liberar sesiones NodoSesion* auxSesion = inicioSesiones; while (auxSesion != NULL) { NodoSesion* temp = auxSesion; auxSesion = auxSesion->FunSiguiente; free(temp); } inicioSesiones = NULL; // Liberar turnos NodoTurno* auxTurno = frenteCola; while (auxTurno != NULL) { NodoTurno* temp = auxTurno; auxTurno = auxTurno->FunSiguiente; free(temp); } frenteCola = NULL; finalCola = NULL; }