Archivos en C/C++ problemas con valores de retorno

Iniciado por Beginner Web, 2 Enero 2019, 03:04 AM

0 Miembros y 1 Visitante están viendo este tema.

Beginner Web

Primero que nada hola, bien, tengo el siguiente programa el cual tiene un modulo de agregar un registro solamente si la clave no existe en el archivo de registros tengo lo siguiente:

Código (cpp) [Seleccionar]
#include <stdio.h>
//EL PROBLEMA ESTA EN EL MODULO "void cargar_docentes(archivo docentes)"
#include <stdlib.h>
#include <string.h>
#include <iostream>

using namespace std;

typedef char tcad[50];
typedef struct tfecha{
int dia;
int mes;
int anyo;
};
typedef struct tformacion{
tcad titulo;
tcad facultad;
tcad universidad;
};
typedef struct tdocente{
int legajo;
tcad nombre_apellido;
tfecha fecha_nac;
tformacion educacion;
int DNI;
tcad cargo;
};
typedef FILE *parchivo;

void cargar(tdocente &docente);
void mostrar(tdocente docente);
void cargar_docentes(parchivo docentes);
bool consulta(parchivo docentes, int codigo);
void mostrar_docentes(parchivo docentes);
void busqueda(parchivo docentes, int codigo);
void modificar_docente(parchivo docentes, int codigo);
void eliminar_docente(parchivo docentes, int codigo);
void listar_docentes_especificos(parchivo docentes, tcad buscado);
void nueva_cadena(tcad &cadena);

int main()
{
parchivo docentes;
int opcion, codigo;
tcad buscado;
do{
system("cls");
cout<<"1. Cargar docente"<<endl;
cout<<"2. Consultar docente"<<endl;
cout<<"3. Listar docentes"<<endl;
cout<<"4. Buscar docente"<<endl;
cout<<"5. Modificar docente"<<endl;
cout<<"6. Eliminar docente"<<endl;
cout<<"7. Listar docentes por universidad"<<endl;
cout<<"8. Salir"<<endl;
cin>>opcion;
switch(opcion){
case 1: cargar_docentes(docentes);break;
case 2: cout<<"Ingrese numero de legajo: ";
cin>>codigo;
if(consulta(docentes,codigo)==true)
cout<<"Docente encontrado"<<endl;
else
cout<<"Docente no encontrado"<<endl;
break;
case 3: mostrar_docentes(docentes);break;
case 4: cout<<"Ingrese numero de legajo: ";
cin>>codigo;
busqueda(docentes,codigo);break;
case 5: cout<<"Ingrese numero de legajo: ";
cin>>codigo;
modificar_docente(docentes,codigo);break;
case 6: cout<<"Ingrese numero de legajo: ";
cin>>codigo;
eliminar_docente(docentes,codigo);break;
case 7: cout<<"Ingrese universidad: ";
nueva_cadena(buscado);
listar_docentes_especificos(docentes,buscado);break;
case 8: cout<<"FIN DEL PROGRAMA"<<endl;break;
default: cout<<"Opcion incorrecta"<<endl;
}
system("pause");
}while(opcion!=8);
}

void cargar(tdocente &docente)
{
cout<<"Ingrese datos del docente"<<endl;
cout<<"Legajo: ";
cin>>docente.legajo;
cout<<"Nombre y apellido: ";
nueva_cadena(docente.nombre_apellido);
cout<<"Fecha de nadimiento DD/MM/AA"<<endl;
cin>>docente.fecha_nac.dia;
cin>>docente.fecha_nac.mes;
cin>>docente.fecha_nac.anyo;
cout<<"Formacion academica"<<endl;
cout<<"Titulo: ";
nueva_cadena(docente.educacion.titulo);
cout<<"Facultad: ";
nueva_cadena(docente.educacion.facultad);
cout<<"Universidad: ";
nueva_cadena(docente.educacion.universidad);
cout<<"DNI: ";
cin>>docente.DNI;
cout<<"Cargo: ";
nueva_cadena(docente.cargo);
}

void mostrar(tdocente docente)
{
cout<<"Datos del docente"<<endl;
cout<<"Legajo: "<<docente.legajo<<endl;
cout<<"Nombre y apellido: "<<docente.nombre_apellido<<endl;
cout<<"Fecha de nadimiento:"<<docente.fecha_nac.dia<<"/"<<docente.fecha_nac.mes<<"/"<<docente.fecha_nac.anyo<<endl;
cout<<"Formacion academica"<<endl;
cout<<"Titulo: "<<docente.educacion.titulo<<endl;
cout<<"Facultad: "<<docente.educacion.facultad<<endl;
cout<<"Universidad: "<<docente.educacion.universidad<<endl;
cout<<"DNI: "<<docente.DNI<<endl;
cout<<"Cargo: "<<docente.cargo<<endl<<endl;
}
//EL PROBLEMA ES ESTE MODULO
void cargar_docentes(parchivo docentes)
{
tdocente d;
docentes=fopen("docentes.txt","ab+");
cargar(d);
fclose(docentes);
if(consulta(docentes,d.legajo)==false){
docentes=fopen("docentes.txt","ab");
fwrite(&d,sizeof(d),1,docentes);
}
else
cout<<"El numero de legajo ya existe"<<endl;
fclose(docentes);
}

bool consulta(parchivo docentes, int codigo)
{
tdocente d;
bool encontrado=false;
docentes=fopen("docentes.txt","rb");
if(docentes!=NULL){
while(!feof(docentes) && !encontrado){
fread(&d,sizeof(d),1,docentes);
if(d.legajo==codigo)
encontrado=true;
}
}
fclose(docentes);
return encontrado;
}

void mostrar_docentes(parchivo docentes)
{
tdocente d;
docentes=fopen("docentes.txt","rb");
if(docentes==NULL)
cout<<"No se pudo abrir el archivo"<<endl;
else{
while(!feof(docentes)){
fread(&d,sizeof(d),1,docentes);
if(!feof(docentes))
mostrar(d);
}
}
fclose(docentes);
}

void busqueda(parchivo docentes, int codigo)
{
tdocente d;
bool encontrado=false;
docentes=fopen("docentes.txt","rb");
if(docentes==NULL)
cout<<"No se pudo abrir el archivo"<<endl;
else{
while(!feof(docentes) && !encontrado){
fread(&d,sizeof(d),1,docentes);
if(d.legajo==codigo){
mostrar(d);
encontrado=true;
}
}
if(encontrado==false)
cout<<"Docente no encontrado"<<endl;
}
fclose(docentes);
}

void modificar_docente(parchivo docentes, int codigo)
{
tdocente d;
bool encontrado=false;
docentes=fopen("docentes.txt","rb+");
if(docentes==NULL)
cout<<"No se pudo abrir el archivo"<<endl;
else{
while(!feof(docentes) && !encontrado){
fread(&d,sizeof(d),1,docentes);
if(codigo==d.legajo)
encontrado=true;
}
if(encontrado==true){
cargar(d);
fseek(docentes,-sizeof(d),1);
fwrite(&d,sizeof(d),1,docentes);
}
else
cout<<"Docente no encontrado"<<endl;
}
fclose(docentes);
}

void eliminar_docente(parchivo docentes, int codigo)
{
tdocente d;
parchivo temporal;
docentes=fopen("docentes.txt","rb");
temporal=fopen("temporal.txt","wb");
if(docentes==NULL){
cout<<"ARCHIVO INEXISTENTE"<<endl;
fclose(docentes);
fclose(temporal);
}
else{
while(!feof(docentes)){
fread(&d,sizeof(d),1,docentes);
if(!feof(docentes) && d.legajo!=codigo)
fwrite(&d,sizeof(d),1,temporal);
}
fclose(docentes);
fclose(temporal);
if(remove("docentes.txt")==0)
rename("temporal.txt","docentes.txt");
else
cout<<"ERROR AL ELIMINAR"<<endl;
}
}

void listar_docentes_especificos(parchivo docentes, tcad buscado)
{
tdocente d;
docentes=fopen("docentes.txt","rb");
if(docentes==NULL)
cout<<"No se pudo abrir el archivo"<<endl;
else{
while(!feof(docentes)){
fread(&d,sizeof(d),1,docentes);
if(!feof(docentes) && strcmp(d.educacion.universidad,buscado)==0)
mostrar(d);
}
}
fclose(docentes);
}

void nueva_cadena(tcad &cadena)
{
fflush(stdin);
gets(cadena);
fflush(stdin);
}


Si bien no me resulta funcional lo que me enseñaron de cerrar el archivo para llamar a la funcion de busqueda que devuelve un valor logico.
Como en este caso:

Código (cpp) [Seleccionar]
void agregar_alumnos(parchivo alumnos)
{
talumno a;
int cantidad;
alumnos=fopen("alumnos.txt","wb");
cout<<"Cuántos registros desea guardar: ";
cin>>cantidad;
while(cantidad>0){
carga(a);
fclose(alumnos);
if(buscar_archivo(alumnos,a.libreta)==false){
alumnos=fopen("alumnos.txt","ab");
fwrite(&a,sizeof(a),1,alumnos);
cantidad--;
}
else
cout<<"La libreta ya existe"<<endl;
}
fclose(alumnos);
}


Pero le he encontrado dos soluciones la primera es algo extraña, no me convence y es cambiar incluir un mensaje en la funcion de busqueda,
cosa que no se hace en funciones.
Es asi:
Código (cpp) [Seleccionar]
bool consulta(parchivo docentes, int codigo)
{
tdocente d;
bool encontrado=false;
docentes=fopen("docentes.txt","rb");
if(docentes!=NULL){
while(!feof(docentes) && !encontrado){
fread(&d,sizeof(d),1,docentes);
if(d.legajo==codigo)
encontrado=true;
cout<<"Encontrado: "<<encontrado<<endl;
}
}
fclose(docentes);
return encontrado;
}


Un poco raro bueno, y la ultima y mas clara diria yo es mantener el archivo abierto al mandar a preguntar si existe o no la clave del registro en
el archivo de registros, asi es como he logrado hacer andar este programa, pero no entiendo bien me explican?

Código (cpp) [Seleccionar]
void cargar_docentes(parchivo docentes)
{
tdocente d;
docentes=fopen("docentes.txt","ab+");
cargar(d);
if(consulta(docentes,d.legajo)==false)
fwrite(&d,sizeof(d),1,docentes);
else
cout<<"El numero de legajo ya existe"<<endl;
fclose(docentes);
}


Intenten agregar con el primer programa agregar como primer registro todos los campos en 1, no les deja pero si ponen todo 2 en los campos del registro si, me perdi muchachos ayuda.  :-(
7w7

fary

En:

Código (cpp) [Seleccionar]
void cargar_docentes(parchivo docentes)
{
tdocente d;
docentes=fopen("docentes.txt","ab+");
cargar(d);
fclose(docentes);
if(consulta(docentes,d.legajo)==false){
docentes=fopen("docentes.txt","ab");
fwrite(&d,sizeof(d),1,docentes);
}
else
cout<<"El numero de legajo ya existe"<<endl;
fclose(docentes);
}


Si el if no se cumple no abres el archivo.... ¿No?

¿Así funciona?

Código (cpp) [Seleccionar]
void cargar_docentes(parchivo docentes)
{
tdocente d;
docentes=fopen("docentes.txt","ab+");
cargar(d);
fclose(docentes);
if(consulta(docentes,d.legajo)==false){
docentes=fopen("docentes.txt","ab");
fwrite(&d,sizeof(d),1,docentes);
                fclose(docentes);
}else{
cout<<"El numero de legajo ya existe"<<endl;
        }
}


saludos!

Un byte a la izquierda.

Beginner Web

#2
Cita de: fary en  2 Enero 2019, 23:05 PM
¿Así funciona?

Código (cpp) [Seleccionar]
void cargar_docentes(parchivo docentes)
{
tdocente d;
docentes=fopen("docentes.txt","ab+");
cargar(d);
fclose(docentes);
if(consulta(docentes,d.legajo)==false){
docentes=fopen("docentes.txt","ab");
fwrite(&d,sizeof(d),1,docentes);
               fclose(docentes);
}else{
cout<<"El numero de legajo ya existe"<<endl;
       }
}


saludos!



No, no funciona, saludos
7w7

MAFUS

#3
¿Por qué haces esto?

docentes=fopen("docentes.txt","ab+");
cargar(d);
fclose(docentes);


Por otra parte y cómo se ha repetido muchas veces: es un error cargar una estructura directamente a un archivo y recuperarla de él totalmente.
C/C++ puede mover los miembros de las estructuras y dejar espacios vacíos entre ellos para que se ajusten en la memoria. En algunas plataformas esto se soluciona serializando estos datos. Pero una forma rápida de resolverlo es grabando en disco miembro a miembro y a la hora de sacarlas leyendo miembro a miembro en el mismo orden.
Si no lo haces de esta forma puede que creas que estas leyendo legajo cuando en realidad estás leyendo nombre_apellidos, por ejemplo.


Me he tomado la libertad de hacerle algunos arreglillos, sobre todo para el tema de que el tamaño teórico de una estructura no es el real y alguna que otra cosa con el manejo de los archivos. Aún así necesita aun muchas mejoras: validar fechas, recibir el tipo de dato esperado desde la consola y toda una larga lista de etcéteras. También lo he pasado a C (C++ no me gusta).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_CADENA 50

typedef struct tfecha {
    int dia;
    int mes;
    int anyo;
} fecha;

typedef struct tformacion {
    char titulo[MAX_CADENA];
    char facultad[MAX_CADENA];
    char universidad[MAX_CADENA];
} formacion;

typedef struct tdocente {
    int legajo;
    char nombre_apellido[MAX_CADENA];
    fecha fecha_nac;
    formacion educacion;
    int DNI;
    char cargo[MAX_CADENA];
} docente;

void grabar_registro(docente *registro, FILE *archivo);
void leer_registro(docente *registro, FILE *archivo);
void cargar(docente *individuo);
void mostrar(docente *individuo);
void cargar_docentes(char * const nombre_archivo);
bool consulta(char * const nombre_archivo, int codigo);
void mostrar_docentes(char * const nombre_archivo);
void busqueda(char * const nombre_archivo, int codigo);
void modificar_docente(char * const nombre_archivo, int codigo);
void eliminar_docente(char * const nombre_archivo, int codigo);
void listar_docentes_especificos(char * const nombre_archivo, char * const buscado);
void nueva_cadena(char cadena[]);

int main() {
    char *docentes = "docentes.txt";
    int opcion, codigo;
    char buscado[MAX_CADENA];
    do {
        system("cls");
        puts("1. Cargar docente");
        puts("2. Consultar docente");
        puts("3. Listar docentes");
        puts("4. Buscar docente");
        puts("5. Modificar docente");
        puts("6. Eliminar docente");
        puts("7. Listar docentes por universidad");
        puts("8. Salir");
        printf("\n> ");
        scanf("%d", &opcion);
        switch(opcion) {
        case 1:
            cargar_docentes(docentes);
            break;
        case 2:
            printf("Ingrese numero de legajo: ");
            scanf("%d", &codigo);
            if(consulta(docentes, codigo))
                puts("Docente encontrado");
            else
                puts("Docente no encontrado");
            break;
        case 3:
            mostrar_docentes(docentes);
            break;
        case 4:
            printf("Ingrese numero de legajo: ");
            scanf("%d", &codigo);
            busqueda(docentes, codigo);
            break;
        case 5:
            printf("Ingrese numero de legajo: ");
            scanf("%d", &codigo);
            modificar_docente(docentes, codigo);
            break;
        case 6:
            printf("Ingrese numero de legajo: ");
            scanf("%d", &codigo);
            eliminar_docente(docentes, codigo);
            break;
        case 7:
            printf("Ingrese universidad: ");
            nueva_cadena(buscado);
            listar_docentes_especificos(docentes, buscado);
            break;
        case 8:
            puts("FIN DEL PROGRAMA");
            break;
        default:
            puts("Opcion incorrecta");
        }
        system("pause");
    } while(opcion!=8);
}

void grabar_registro(docente *registro, FILE *archivo) {
    fwrite(&registro->legajo, sizeof(int), 1, archivo);
    fwrite(registro->nombre_apellido, sizeof(char), MAX_CADENA, archivo);
    fwrite(&registro->fecha_nac.dia, sizeof(int), 1, archivo);
    fwrite(&registro->fecha_nac.mes, sizeof(int), 1, archivo);
    fwrite(&registro->fecha_nac.anyo, sizeof(int), 1, archivo);
    fwrite(registro->educacion.titulo, sizeof(char), MAX_CADENA, archivo);
    fwrite(registro->educacion.facultad, sizeof(char), MAX_CADENA, archivo);
    fwrite(registro->educacion.universidad, sizeof(char), MAX_CADENA, archivo);
    fwrite(&registro->DNI, sizeof(int), 1, archivo);
    fwrite(registro->cargo, sizeof(char), MAX_CADENA, archivo);
}

void leer_registro(docente *registro, FILE *archivo) {
    fread(&registro->legajo, sizeof(int), 1, archivo);
    fread(registro->nombre_apellido, sizeof(char), MAX_CADENA, archivo);
    fread(&registro->fecha_nac.dia, sizeof(int), 1, archivo);
    fread(&registro->fecha_nac.mes, sizeof(int), 1, archivo);
    fread(&registro->fecha_nac.anyo, sizeof(int), 1, archivo);
    fread(registro->educacion.titulo, sizeof(char), MAX_CADENA, archivo);
    fread(registro->educacion.facultad, sizeof(char), MAX_CADENA, archivo);
    fread(registro->educacion.universidad, sizeof(char), MAX_CADENA, archivo);
    fread(&registro->DNI, sizeof(int), 1, archivo);
    fread(registro->cargo, sizeof(char), MAX_CADENA, archivo);
}

void cargar(docente *individuo) {
    puts("Ingrese datos del docente");
    printf("Legajo: ");
    scanf("%d", &individuo->legajo);
    printf("Nombre y apellido: ");
    nueva_cadena(individuo->nombre_apellido);
    puts("Fecha de nacimiento...");
    printf("Dia: ");
    scanf("%d", &individuo->fecha_nac.dia);
    printf("Mes: ");
    scanf("%d", &individuo->fecha_nac.mes);
    printf("Anyo: ");
    scanf("%d", &individuo->fecha_nac.anyo);
    puts("Formacion academica");
    printf("Titulo: ");
    nueva_cadena(individuo->educacion.titulo);
    printf("Facultad: ");
    nueva_cadena(individuo->educacion.facultad);
    printf("Universidad: ");
    nueva_cadena(individuo->educacion.universidad);
    printf("DNI: ");
    scanf("%d", &individuo->DNI);
    printf("Cargo: ");
    nueva_cadena(individuo->cargo);
}

void mostrar(docente *individuo) {
    puts("Datos del docente");
    printf("Legajo: %d\n", individuo->legajo);
    printf("Nombre y apellido: %s\n", individuo->nombre_apellido);
    printf("Fecha de nacimiento: %d/%d/%d\n", individuo->fecha_nac.dia, individuo->fecha_nac.mes, individuo->fecha_nac.anyo);
    puts("Formacion academica");
    printf("Titulo: %s\n", individuo->educacion.titulo);
    printf("Facultad: %s\n", individuo->educacion.facultad);
    printf("Universidad: %s\n", individuo->educacion.universidad);
    printf("DNI: %d\n", individuo->DNI);
    printf("Cargo: %s\n\n", individuo->cargo);
}

void cargar_docentes(char * const nombre_archivo) {
    docente d;
    FILE *fp;
    cargar(&d);
    if(consulta(nombre_archivo, d.legajo)==false) {
        fp=fopen(nombre_archivo, "ab");
        grabar_registro(&d, fp);
        fclose(fp);
    }
    else
        puts("El numero de legajo ya existe");
}

bool consulta(char * const nombre_archivo, int codigo) {
    docente d;
    char c;
    bool encontrado=false;
    FILE *fp=fopen(nombre_archivo,"rb");
    if(fp) {
        c=fgetc(fp);
        while(!feof(fp) && !encontrado) {
            ungetc(c, fp);
            leer_registro(&d, fp);
            if(d.legajo==codigo)
                encontrado=true;
            c=fgetc(fp);
        }
    }
    fclose(fp);
    return encontrado;
}

void mostrar_docentes(char * const nombre_archivo) {
    docente d;
    char c;
    FILE *fp=fopen(nombre_archivo, "rb");
    if(!fp) {
        puts("No se pudo abrir el archivo");
        return;
    }
    c=fgetc(fp);
    while(!feof(fp)) {
        ungetc(c, fp);
        leer_registro(&d, fp);
        mostrar(&d);
        c=fgetc(fp);
    }
    fclose(fp);
}

void busqueda(char * const nombre_archivo, int codigo) {
    docente d;
    char c;
    bool encontrado=false;
    FILE *fp=fopen(nombre_archivo, "rb");
    if(!fp) {
        puts("No se pudo abrir el archivo");
        return;
    }
    c=fgetc(fp);
    while(!feof(fp) && !encontrado) {
        ungetc(c, fp);
        leer_registro(&d, fp);
        if(d.legajo==codigo) {
            mostrar(&d);
            encontrado=true;
        }
        c=fgetc(fp);
    }
    if(encontrado==false)
        puts("Docente no encontrado");
    fclose(fp);
}

void modificar_docente(char * const nombre_archivo, int codigo) {
    docente d;
    char c;
    long int posicion = 0;
    bool encontrado=false;
    FILE *fp=fopen(nombre_archivo, "rb+");
    if(!fp) {
        puts("No se pudo abrir el archivo");
        return;
    }
    c=fgetc(fp);
    while(!feof(fp) && !encontrado) {
        ungetc(c, fp);
        leer_registro(&d, fp);
        if(codigo==d.legajo)
            encontrado=true;
        else
            posicion = ftell(fp);
        c=fgetc(fp);
    }
    if(encontrado) {
        ungetc(c, fp);
        cargar(&d);
        fseek(fp, posicion, SEEK_SET);
        grabar_registro(&d, fp);
    }
    else
        puts("Docente no encontrado");
    fclose(fp);
}

void eliminar_docente(char * const nombre_archivo, int codigo) {
    const char *nombre_temporal = "temporal.txt";
    docente d;
    char c;
    FILE *fp;
    FILE *temporal;
    fp=fopen(nombre_archivo, "rb");
    if(!fp) {
        printf("No se puede abrir el archivo %s\n", nombre_archivo);
        return;
    }
    temporal=fopen(nombre_temporal, "wb");
    if(!temporal) {
        puts("No se pudo generar el archivo temporal.");
        fclose(fp);
        return;
    }
    c=fgetc(fp);
    while(!feof(fp)) {
        ungetc(c, fp);
        leer_registro(&d, fp);
        if(!feof(fp) && d.legajo!=codigo)
            grabar_registro(&d, temporal);
        c=fgetc(fp);
    }
    fclose(fp);
    fclose(temporal);
    if(remove(nombre_archivo)==0)
        rename(nombre_temporal, nombre_archivo);
    else
        puts("ERROR AL ELIMINAR");
}

void listar_docentes_especificos(char * const nombre_archivo, char * const buscado) {
    docente d;
    char c;
    FILE *fp = fopen(nombre_archivo, "rb");
    if(!fp) {
        puts("No se pudo abrir el archivo");
        return;
    }
    c=fgetc(fp);
    while(!feof(fp)) {
        ungetc(c, fp);
        leer_registro(&d, fp);
        if(strcmp(d.educacion.universidad, buscado)==0)
            mostrar(&d);
        c=fgetc(fp);
    }
    fclose(fp);
}

void nueva_cadena(char cadena[]) {
    char *c;
    fseek(stdin, 0, SEEK_END);
    fgets(cadena, MAX_CADENA, stdin);
    c = strchr(cadena, '\n');
    if(c)
        *c = '\0';
    fseek(stdin, 0, SEEK_END);
}