I am currently working on a small college project in which I have to read and write from a file and be able to perform basic CRUD operations. I am struggling with the "update" section of this project.
Sometimes the editRecord() function will work as expected and other times it will not, resulting in duplicated values in the empleados vector, which eventually will duplicate the lines in the output file. I know the code might lack proper memory management since I am a beginner C programmer, so I am hoping to receive some feedback on how to improve my code, but most importantly, on how to solve the undesirable behavior.
Here's the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
char departamentos[6][15] = {"RRHH", "Consultoria", "Design", "Produccion", "Calidad", "Distribucion"};
char cargos[6][15] = {"Gerente", "Supervisor", "Analista", "Designer", "Desarrollador", "Auditor"};
/* Modelo de empleado */
typedef struct
{
unsigned int cedula;
char nombre[30];
char apellido[30];
float sueldo;
char departamento[15];
char cargo[15];
char fecha_ingreso[15];
} Empleado;
/* Fin modelo empleado */
/* Prototipos */
void newRecord(Empleado empleados[], int *size);
void showRecords(Empleado empleados[], int size);
void showRecord(Empleado empleado);
int editRecord(int index, Empleado empleados[]);
void deleteRecord();
int saveRecords(Empleado empleados[], int size, char *filename);
int loadRecords(Empleado empleados[], char *filename);
int findRecord(Empleado empleados[], int size);
int highestLowest(Empleado empleados[], int size);
/* Fin Prototipos */
#define N 200
int main()
{
Empleado empleados[N];
int option;
int searchIndex;
int searchMode;
Empleado searchEmpleado;
int size = loadRecords(empleados, "trabajadores.in");
// printf("current dimension: %i",size);
while (option != 7)
{
printf("================ Menu principal ================\n");
printf("Seleccione una opcion: \n 1-Nuevo empleado \n 2-Buscar empleado \n 3-Listar empleados \n 4-Modificar \n 5-Eliminar \n 6-Guardar cambios \n 7-Salir\n");
printf("Ingrese una opcion: ");
scanf("%i", &option);
switch (option)
{
case 1:
newRecord(empleados, &size);
break;
case 2:
while (searchMode < 1 || searchMode > 4)
{
printf("Introduzca el criterio de busqueda deseado (1-CI 4-Mayor y menor sueldo): ");
scanf(" %i", &searchMode);
if (searchMode < 1 || searchMode > 4)
{
printf("Criterio de busqueda invalido, intente nuevamente");
}
}
if (searchMode == 1)
{
searchIndex = findRecord(empleados, size);
searchEmpleado = empleados[searchIndex];
printf("\n");
showRecord(searchEmpleado);
printf("\n");
}
if (searchMode == 4)
{
highestLowest(empleados, size);
}
break;
case 3:
printf("================ Empleados activos ================\n");
showRecords(empleados, size);
printf("===================================================\n");
break;
case 4:
searchIndex = findRecord(empleados, size);
if (searchIndex > -1)
{
editRecord(searchIndex, empleados);
}
break;
case 5:
deleteRecord();
break;
case 6:
saveRecords(empleados, size, "trabajadores.in");
break;
case 7:
saveRecords(empleados, size, "trabajadores.in");
break;
default:
printf("Opcion invalida, intente nuevamente\n");
break;
}
};
return 0;
}
/* Cargar datos existentes en el vector empleados[] */
int loadRecords(Empleado empleados[], char *filename)
{
int recordCount;
Empleado empleado;
char dep[10];
char cargo[10];
char nombre[10];
FILE *file = fopen(filename, "r");
int index = 0;
while (!feof(file))
{
fscanf(file, "%u %s %s %s %s %s %f", &empleado.cedula, &nombre, &empleado.apellido, &empleado.departamento, &empleado.cargo, &empleado.fecha_ingreso, &empleado.sueldo);
empleados[index] = empleado;
strncpy(empleados[index].nombre, nombre,sizeof(empleados[index].nombre));
empleados[index].nombre[sizeof(empleados[index].nombre -1 )] = '\0';
index++;
}
return index;
}
/* Crear nuevo registro en el vector empleados[] */
void newRecord(Empleado empleados[], int *size)
{
int aux, aux2;
printf("Introduzca la informacion del empleado\n");
printf("Nombre: ");
scanf("%s", &empleados[*size].nombre);
printf("Apellido: ");
scanf("%s", &empleados[*size].apellido);
printf("Cedula: ");
scanf("%u", &empleados[*size].cedula);
printf("Sueldo: ");
scanf("%f", &empleados[*size].sueldo);
printf("Departamento (1-RRHH 2-Consultoria 3-Design 4-Produccion 5-Calidad 6-Distribucion): ");
scanf("%i", &aux);
printf("Cargo (1-Gerente 2-Supervisor 3-Analista 4-Designer 5-Desarrollador 6-Auditor): ");
scanf("%i", &aux2);
printf("Fecha de ingreso (DD/MM/YYYY): ");
scanf("%s", &empleados[*size].fecha_ingreso);
/* Asignamos el departamento y el cargo al nuevo registro */
strcpy(empleados[*size].departamento, departamentos[aux - 1]);
strcpy(empleados[*size].cargo, cargos[aux2 - 1]);
(*size)++;
printf("new dimension %u", *size);
}
int saveRecords(Empleado empleados[], int size, char *filename)
{
int i;
FILE *file = fopen(filename, "w");
if (file == NULL)
{
printf("Error opening file.");
exit(1);
}
for (i = 0; i < size; i++)
{
fprintf(file, "%u %s %s %s %s %s %.02f\n", empleados[i].cedula, empleados[i].nombre, empleados[i].apellido, empleados[i].departamento, empleados[i].cargo, empleados[i].fecha_ingreso, empleados[i].sueldo);
}
fclose(file);
}
/* Listar todos los registros existentes */
void showRecords(Empleado empleados[], int size)
{
for (int i = 0; i < size; i++)
{
printf("Empleado %d:\n", i + 1);
showRecord(empleados[i]);
printf("\n");
}
}
/* Listar un registro individualmente */
void showRecord(Empleado empleado)
{
printf("Nombre: %s\n", empleado.nombre);
printf("Apellido: %s\n", empleado.apellido);
printf("Cedula: %u\n", empleado.cedula);
printf("Sueldo: %.2f\n", empleado.sueldo);
printf("Departamento: %s\n", empleado.departamento);
printf("Cargo: %s\n", empleado.cargo);
printf("Fecha ingreso: %s\n", empleado.fecha_ingreso);
}
/* Editar información de un registro en el vector empleados[] */
int editRecord(int index, Empleado empleados[])
{
bool edit = true;
int option,aux,aux2;
Empleado empleadoEdit = empleados[index];
printf("Editando CI: %i\n", empleadoEdit.cedula);
while (edit || option != 6)
{
printf("Opciones (1-Nombre 2-Apellido 3-Departamento 4-Cargo 5-Salario 6-Salir): ");
scanf("%i",&option);
switch (option)
{
case 1:
printf("Ingrese el nuevo nombre: ");
scanf("%s", &empleadoEdit.nombre);
break;
case 2:
printf("Ingrese el nuevo apellido: ");
scanf("%s", &empleadoEdit.apellido);
break;
case 3:
printf("Ingrese el nuevo departamento (1-RRHH 2-Consultoria 3-Design 4-Produccion 5-Calidad 6-Distribucion): ");
scanf("%i", &aux);
/* Asignamos el nuevo departamento */
strcpy(empleadoEdit.departamento, departamentos[aux - 1]);
break;
case 4:
printf("Ingrese el nuevo cargo (1-Gerente 2-Supervisor 3-Analista 4-Designer 5-Desarrollador 6-Auditor):: ");
scanf("%i", &aux2);
/* Asignamos el nuevo cargo */
strcpy(empleadoEdit.cargo, cargos[aux2 - 1]);
break;
case 5:
printf("Ingrese el nuevo salario: ");
scanf(" %f", &empleadoEdit.sueldo);
break;
case 6:
edit = false;
break;
default:
printf("Opcion invalida,intente nuevamente.\n");
break;
}
}
empleados[index] = empleadoEdit;
return 0;
}
void deleteRecord()
{
}
int findRecord(Empleado empleados[], int size)
{
unsigned int ci;
printf("Introduzca la cedula del empleado a buscar: ");
scanf("%u", &ci);
for (int i = 0; i < size; i++)
{
if (ci == empleados[i].cedula)
{
return i;
}
}
printf("No se ha encontrado ningun registro con los parametros proporcionados\n\n");
return -1;
}
int highestLowest(Empleado empleados[], int size)
{
int lowestIndex, highestIndex;
int lowestSalary = 9999999;
int highestSalary = 0;
for (int i = 0; i < size; i++)
{
if (empleados[i].sueldo < lowestSalary)
{
lowestSalary = empleados[i].sueldo;
lowestIndex = i;
}
if (empleados[i].sueldo > highestSalary)
{
highestSalary = empleados[i].sueldo;
highestIndex = i;
}
}
printf("\nEmpleado con mayor salario \n");
showRecord(empleados[highestIndex]);
printf("\n");
printf("Empleado con menor salario \n");
showRecord(empleados[lowestIndex]);
printf("\n");
return 0;
}
and this is the format of the output file
7569984 Pedro Diaz RRHH Gerente 29/2/2009 1200.00
8987565 Luisa Garcia Produccion Supervisor 25/3/2015 1050.00
1565988 Josefa Cerdenas Produccion Desarrollador 18/4/2012 800.00
5456748 Maria Gonzalez Calidad Auditor 30/1/2020 780.00
9400670 Miguel Diaz Distribucion Auditor 1/11/2010 780.00
6700960 Ana Mendez Calidad Supervisor 25/3/2015 1120.00
8760200 Andres Lopez Design Designer 12/5/2015 850.00
7890450 Fanny Gonzalez Consultoria Analista 15/1/2018 690.00
5670320 Juan Mendoza Consultoria Supervisor 19/8/2017 920.00
7430120 Jessica Martinez RRHH Analista 17/3/2011 870.00
1 Max MM Consultoria Supervisor 12/10/2024 1200.00
2 Zain Rondon Calidad Supervisor 12/10/2024 40.00
Editing using editRecord method will result in the duplication of the next value in the array as seen in the image.