//Ejemplo fread, fwrite
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

typedef struct{
    char nombre[30];
    char ciudad[30];
    int edad;
}pers;

FILE *archivo=NULL;   //Archivo como variable global.
char n_archivo[20];

void CrearArchivo(char *n_archivo);  //Crea un archivo.
void AgregarPersona(void);           //Agrega personas al archivo creado.
void MostrarPersonas(void);          //Muestra a las personas guardadas.
void NombreArchivo(void);            //Da nombre a archivo para utilizarlo en funciones.
void BorrarPersona(void);            //Borra una persona del archivo

int main()
{
    char opcion;
    while(1)
    {
        system("cls"); //Menu
        printf("1.- Crear Archivo\n"
               "2.- Agregar Persona\n"
               "3.- Mostrar Personas\n"
               "4.- Borrar Persona\n"
               "5.- Cargar Archivo\n"
               "6.- Salir\n");
        while(opcion=getch(), opcion<'1' || opcion>'6');
        switch(opcion)
        {
            case '1':
                CrearArchivo(n_archivo);break;
            case '2':
                AgregarPersona();break;
            case '3':
                MostrarPersonas();break;
            case '4':
                BorrarPersona();break;
            case '5':
                NombreArchivo();break;
            case '6':
                system("pause");
                return 0;
        }
        system("pause");
    }
}

void CrearArchivo(char *n_archivo) //Genera archivo vacio.
{
    printf("****************************\n"
           "\tCrear Archivo\n"
           "****************************\n");
    printf("Ingrese nombre del archivo a crear:\n");
    gets(n_archivo);
    strcat(n_archivo, ".dat"); //Agrega .dat al string de nombre.
    archivo=fopen(n_archivo,"wb"); //Abierto para escritura.
    if(!archivo)
    {
        printf("No se pudo crear archivo.\n");
        return;
    }
    fclose(archivo);  //Se cierra archivo.
}

void AgregarPersona(void)
{
    pers aux;
        printf("****************************\n"
               "\tAgregar Persona\n"
               "****************************\n");
    archivo=fopen(n_archivo,"ab"); //Se abre archivo para agregar datos desde final del archivo.
    if(!archivo)
    {
        printf("No hay archivo abierto\n");
        return;
    }

    printf("Ingrese nombre: ");
    gets(aux.nombre);
    printf("Ingrese ciudad: ");
    gets(aux.ciudad);
    printf("Ingrese edad: ");
    scanf("%d", &aux.edad);
    fflush(stdin);
    fwrite(&aux, sizeof(pers), 1, archivo); //Se escribe en el archivo.
    fclose(archivo); //Se cierra.
    printf("\nPersona Agregada!\n");
}

void MostrarPersonas(void)
{
    pers aux;
    int n=1;
            printf("****************************\n"
                   "\tMostrar Personas\n"
                   "****************************\n");
    archivo=fopen(n_archivo,"rb"); //Se abre archivo en modo lectura.
    if(!archivo)
    {
        printf("No hay archivo abierto\n");
        return;
    }
    while(fread(&aux,sizeof(pers), 1, archivo)!=0)//Se lee hasta que ya no hayan mas datos que leer.
    {
        printf("Persona %d:\n\n"
               "Nombre: %s\n"
               "Ciudad %s\n"
               "Edad %d\n", n, aux.nombre, aux.ciudad, aux.edad);
        n++;
    }
    fclose(archivo);
}
void NombreArchivo(void)
{
    printf("****************************\n"
           "\tCargar Archivo\n"
           "****************************\n");
    printf("Escriba nombre del archivo:\n");
    fgets(n_archivo, 20, stdin);  //Da nombre a archivo, se pudo hacer con gets, pero es para probar que tambien se puede con fgets.
    strtok(n_archivo, "\n");      //Elimina salto de linea agregado por fgets
    strcat(n_archivo, ".dat");
    if(archivo)  //Si hay archivo abierto lo cierra.
        fclose(archivo);
}

void BorrarPersona(void)
{
    FILE *aux_arch;
    pers aux;
    int borrado=0;
    char n_borrar[30];
    printf("****************************\n"
           "\tBorrar Persona\n"
           "****************************\n");

    archivo=fopen(n_archivo, "rb");  //Se abre archivo para modo lectura.

    if(!archivo) //Se abrio correctamente?
    {
        printf("No hay archivo abierto para borrar persona.\n");
        return;
    }
    aux_arch=fopen("auxiliar.aux", "wb"); //Se crea archivo auxiliar.
    if(!aux_arch) //Se pudo crear archivo?
    {
        printf("NO se pudo crear archivo auxiliar.\n");
        return;
    }
    printf("Ingrese nombre de persona a borrar:\n");
    gets(n_borrar); //Se ingresa nombre de la persona que se desea borrar
    while(fread(&aux, sizeof(pers),1,archivo)!=0) //Mientras hayan datos que leer.
    {
         if(strcmp(aux.nombre,n_borrar)!=0) //Se compara dato a dato
            fwrite(&aux,sizeof(pers),1,aux_arch); //Mientras no sea la persona que se desea borrar, se escribe en archivo auxiliar.
        else
            borrado=1;  //Si se borro una persona, esta variable indica que efectivamente se borro.
    }
    fclose(aux_arch); //Se cierran archivos.
    fclose(archivo);
    if(borrado)  //Si se borro persona
    {
        remove(n_archivo); //Se borra el archivo original
        rename("auxiliar.aux",n_archivo); //Se renombra archivo auxiliar
        printf("Se ha borrado la persona seleccionada.\n");
    }
    else{
        remove("auxiliar.aux"); //Sino hubo exito se borra archivo auxiliar.
        printf("No se ha encontrado persona a borrar.\n");
    }
}
