Related
I cant get this program to work.
It should convert capital letters to normal and vice versa, and numberso into three asterisks (***), and rewrite the file that i give as an argument with said changes, mapped into memory.
The parent process must do the letter conversion, and the child process must do the numbers. They must procceed in halves: the first half of the file, and then the second half of it. The first half seems to be doing fine, but the second one is all corrupted.
I tried making buffer a char *buffer, and using the various methos commented in the code, but nothing seems to work properly.
Here is the code and output:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
// Comprobamos que se haya proporcionado un nombre de archivo como argumento
if (argc < 2) {
printf("Error: se debe proporcionar el nombre del archivo como argumento.\n");
exit(EXIT_FAILURE);
}
// Abrimos el archivo en modo lectura/escritura
int file = open(argv[1], O_RDWR);
if (file < 0) {
printf("Error: no se puede abrir el archivo %s.\n", argv[1]);
exit(EXIT_FAILURE);
}
// Obtenemos el estado del archivo
struct stat estado;
if (fstat(file, &estado) < 0) {
printf("Error: no se puede obtener el estado del archivo %s.\n", argv[1]);
exit(EXIT_FAILURE);// Función que se ejecuta cuando se recibe una señal
}
// Comprobamos que el archivo sea un archivo regular
if (!S_ISREG(estado.st_mode)) {
printf("Error: %s no es un archivo regular.\n", argv[1]);
exit(EXIT_FAILURE);
}
// Mapeamos el archivo en memoria
char *map = (char*) mmap(NULL, estado.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, file, 0);
if (map == MAP_FAILED) {
printf("Error: no se puede mapear el archivo %s en memoria.\n", argv[1]);
exit(EXIT_FAILURE);
}
printf("\n---------------PROCESO DE LECTURA EN CURSO---------------\n");
char texto ='\0';
int lr = 0;
for (int i = 0; i < estado.st_size; i++) {
// Comenzamos a leer el archivo
if ((lr = read(file, &texto, 1)) < 0) {
printf("\nError intentando leer el archivo\n");
exit(EXIT_FAILURE);
}
// Comprobamos que se está leyendo correctamente el contenido del archivo (y cuál es)
printf("%c", texto);
}
// Creamos un proceso hijo
pid_t pid = fork();
if (pid < 0) {
printf("Error: no se puede crear el proceso hijo.\n");
exit(EXIT_FAILURE);
}
if (pid == 0) {
// Proceso hijo
// Esperamos a que el padre procese la mitad del archivo
raise(SIGSTOP); // Paramos el proceso para esperar la señal del padre
int mitadArchivo = estado.st_size / 2;
// Obtenemos el tamaño final del archivo (con la sustitución de números por asteriscos)
int tamanioFinal = estado.st_size;
for (int i = 0; i < estado.st_size; i++) {
if (isdigit(map[i])) {
tamanioFinal += 2;
}
}
// Redimensionamos el archivo para ajustarlo al tamaño final
if (ftruncate(file, tamanioFinal) < 0) {
printf("Error: no se puede redimensionar el archivo %s.\n", argv[1]);
exit(EXIT_FAILURE);
}
// Procesamos la segunda mitad del archivo
char buffer[/*mitadArchivo*/estado.st_size];
int j = 0, k = 0;
printf("\n---------IMPRIMIR DESDE EL HIJO---------\n");
for (int i = 0; i < estado.st_size; i++) {
if (isdigit(map[i])) {
// Si el caracter es un número, lo sustituimos por tres asteriscos
buffer[j++] = '*';
buffer[j++] = '*';
buffer[j++] = '*';
} else {
// Si el caracter no es un número, lo copiamos tal cual al buffer
buffer[j++] = map[i];
}
printf("%c", buffer[i]);
if (i == mitadArchivo) { // Hemos llegado a la mitad
memcpy(map, buffer, /*2*(estado.st_size + j)*/ mitadArchivo + j); // Escribimos la primera mitad ya modificada
raise(SIGSTOP); // Paramos el proceso para esperar la señal del padre
printf("\nSegunda mitad del archivo: \n");
if (isdigit(map[i])) {
// Si el caracter es un número, lo sustituimos por tres asteriscos
buffer[k++] = '*';
buffer[k++] = '*';
buffer[k++] = '*';
} else {
// Si el caracter no es un número, lo copiamos tal cual al buffer
buffer[k++] = map[i];
}
memcpy(buffer, map + (mitadArchivo + j), /*2*(estado.st_size + j)*/ tamanioFinal - (mitadArchivo + j)); // Leemos la segunda mitad que queda por transformar
}
}
printf("\n");
// Copiamos el contenido del buffer al archivo
//memcpy(map /*+ mitadArchivo*/, buffer, j);
// Modificamos el tamaño del archivo para que tenga en cuenta los cambios
//ftruncate(file, 2*(estado.st_size + j) /*- mitadArchivo*/);
// Finalizamos el proceso hijo
exit(EXIT_SUCCESS);
} else {
// Proceso padre
// Procesamos la primera mitad del archivo
char buffer[estado.st_size];
int mitadArchivo = estado.st_size / 2;
int j = 0;
for (int i = 0; i < estado.st_size /*/ 2*/; i++) {
if (islower(map[i])) {
// Si el caracter es una letra minúscula, la convertimos en mayúscula
buffer[j++] = toupper(map[i]);
} else if (isupper(map[i])) {
// Si el caracter es una letra mayúscula, la convertimos en minúscula
buffer[j++] = tolower(map[i]);
} else {
// Si el caracter no es una letra, lo copiamos tal cual al buffer
buffer[j++] = map[i];
}
if (i == estado.st_size / 2){
sleep(1);
// Copiamos el contenido del buffer al archivo
memcpy(map, buffer, j);
// Indicamos al proceso hijo que puede continuar
kill(pid, SIGCONT);
}
}
// Copiamos el contenido del buffer al archivo
memcpy(buffer, map, j);
sleep(1);
// Indicamos al proceso hijo que puede continuar
kill(pid, SIGCONT);
// Esperamos a que el proceso hijo termine
waitpid(pid, NULL, 0);
printf("\n---------IMPRIMIR DESDE LA SALIDA DESDE MEMORIA---------\n");
for (int i = 0; i < estado.st_size; i++)
printf("%c", map[i]);
printf("\n");
// Finalizamos el proceso padre
exit(EXIT_SUCCESS);
}
return 0;
}
Output:
---------------PROCESO DE LECTURA EN CURSO---------------
esta 5 es 6 la
prueba 89 para 531 ver si
35 el programa 7 funciona
---------IMPRIMIR DESDE EL HIJO---------
ESTA *** ES *** LA
PRUEBA ****** P
Segunda mitad del archivo:
ARA ********* ARA ********* ���c�
---------IMPRIMIR DESDE LA SALIDA DESDE MEMORIA---------
ESTA *** ES *** LA
PRUEBA ****** PARA ********* ���c���of�/����
This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 5 months ago.
I have a program that seems to have a problem displaying the data received from a .txt file with fgets
Basically the program is something similar to a CRUD or ABM (in Spanish).
The problem is that when I show the structs from the file, it shows me a duplicate of the last struct.
The code is the following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
// ==== Estructura Empleado ====
typedef struct
{
int legajo; // Numero de 6 digitos
char nombreApellido[30];
float sueldo; // Aleatorio entre 80k-200k
} Empleado;
// Carga un empleado por teclado; Devuelve un struct Empleado
Empleado cargarEmpleadoPorTeclado();
// Carga un vector de Empleado
void cargarEmpleadosPorTeclado(Empleado empleados[], int cantidadEmpleados);
// Recibe un vector de chars y devuelve un struct Empleado
Empleado parsearEmpleado(char datosSinParsear[50], int largoDatos);
// Carga los empleados desde el archivo al vector empleados[]
void cargarEmpleadosEnVector(Empleado empleados[], int cantidadEmpleados);
// Guarda los empleados en el archivo 'empleados.txt'
void guardarEmpleados(Empleado empleados[], int cantidadEmpleados);
// Muestra los empleados cargados en el vector empleados[]
void mostrarEmpleadosDesdeArchivo(int cantidadEmpleados, int eliminados);
// Busca un empleado por legajo en el archivo 'empleados.txt' y lo 'elimina'
void eliminarEmpleadoPorLegajo(Empleado empleados[], int legajo, int cantidadEmpleados, int * eliminados);
void eliminarEmpleadoVectorPorLegajo(Empleado empleados[], int legajo, int cantidadEmpleados, int *eliminados);
void menu(Empleado empleados[], int cantidadEmpleados);
/* ==== Funcion main ==== */
int main()
{
int cantidadEmpleados = 100;
Empleado empleados[cantidadEmpleados];
menu(empleados, cantidadEmpleados);
return 0;
}
/* ==== Implementaciones ==== */
Empleado cargarEmpleadoPorTeclado()
{
Empleado empleado;
printf("\nIngrese el Nombre y Apellido del empleado: ");
fflush(stdin);
gets(empleado.nombreApellido);
printf("\nIngrese el numero de Legajo del empleado: ");
fflush(stdin);
scanf("%d", &empleado.legajo);
empleado.sueldo = 80000 + rand() % (200000-80000);
return empleado;
}
void cargarEmpleadosPorTeclado(Empleado empleados[], int cantidadEmpleados)
{
for (int i = 0; i < cantidadEmpleados; i++)
{
empleados[i] = cargarEmpleadoPorTeclado();
}
guardarEmpleados(empleados, cantidadEmpleados);
}
Empleado parsearEmpleado(char datosSinParsear[], int largoDatos)
{
Empleado empleado;
int delimitador1 = -1;
int delimitador2 = -1;
char auxiliarLegajo[10] = " ";
char auxiliarNombreApellido[30] = " ";
char auxiliarSueldo[10] = " ";
for(int i = 0; i < largoDatos; i++)
{
// Recorro el string hasta encontrar la primera ocurrencia
// Notese que i = largoDatos es para forzar la salida del for y no sobreescribir el valor de delimitador1
// con la segunda ocurrencia
if(datosSinParsear[i] == ';')
{
delimitador1 = i;
i = largoDatos;
}
}
// Recorro el string a partir de la posicion siguiente de la primera ocurrencia
for (int i = delimitador1 + 1; i < largoDatos; i++)
{
if (datosSinParsear[i] == ';')
{
delimitador2 = i;
}
}
if ((delimitador1 != -1) && (delimitador2 != -1))
{
// Desde 0 hasta delimitador1 tenemos el legajo
for (int i = 0; i < delimitador1; i++)
{
auxiliarLegajo[i] = datosSinParsear[i];
}
// Desde delimitador1+1 hasta delimitador2 tenemos el nombre y apellido
for (int i = delimitador1 + 1; i < delimitador2; i++)
{
auxiliarNombreApellido[i - delimitador1 - 1] = datosSinParsear[i];
}
// Desde delimitador2+1 hasta largoDatos tenemos el sueldo en float
for (int i = delimitador2 + 1; i < strlen(datosSinParsear); i++)
{
auxiliarSueldo[i - delimitador2 - 1] = datosSinParsear[i];
}
empleado.legajo = atoi(auxiliarLegajo);
strcpy(empleado.nombreApellido, auxiliarNombreApellido);
empleado.sueldo = atof(auxiliarSueldo);
return empleado;
}
}
void cargarEmpleadosEnVector(Empleado empleados[], int cantidadEmpleados)
{
// Intentamos abrir el archivo y verificamos si no es un puntero nulo
FILE * archivoEmpleados = fopen("empleados.txt", "r");
if(archivoEmpleados != NULL)
{
int i = 0;
while (!feof(archivoEmpleados) && (i < cantidadEmpleados))
{
char datosSinParsear[50] = "";
Empleado empleadoActual;
// Leemos los datos y lo parseamos
fgets(datosSinParsear, 50, archivoEmpleados);
empleadoActual = parsearEmpleado(datosSinParsear, 50);
// Lo asignamos a la posicion actual del vector 'empleados[]'
empleados[i] = empleadoActual;
i++;
}
fclose(archivoEmpleados);
}
// Si el archivo no existe o no lo encuentra
else
{
printf("\nImposible leer los empleados\nEl archivo \"empleados.txt\" no existe o no se encuentra en la ruta actual");
exit(-1);
}
}
void guardarEmpleados(Empleado empleados[], int cantidadEmpleados)
{
// Intentamos abrir el archivo y verificamos si no es un puntero nulo
FILE * archivoEmpleados = fopen("empleados.txt", "w");
if(archivoEmpleados != NULL)
{
for (int i = 0; i < cantidadEmpleados; i++)
{
// Grabamos los datos linea por linea con el formato 'legajo;nombreapellido;sueldo'
fprintf(archivoEmpleados, "%d;%s;%.2f\n", empleados[i].legajo, empleados[i].nombreApellido, empleados[i].sueldo);
}
printf("\nEmpleados guardados exitosamente en \"empleados.txt\"");
fclose(archivoEmpleados);
}
// Si el archivo no existe o no lo encuentra
else
{
printf("\nImposible guardar los empleados\nEl archivo \"empleados.txt\" no existe o no se encuentra en la ruta actual");
exit(-1);
}
}
void mostrarEmpleadosDesdeArchivo(int cantidadEmpleados, int eliminados)
{
FILE * archivoEmpleados = fopen("empleados.txt", "r");
int i = 0;
while(!feof(archivoEmpleados) && i < (cantidadEmpleados-eliminados))
{
char datosSinParsear[50] = "";
fgets(datosSinParsear, 50, archivoEmpleados);
Empleado empleadoActual;
empleadoActual = parsearEmpleado(datosSinParsear, 50);
printf("\nEmpleado");
printf("\n\t* Numero de legajo: %d", empleadoActual.legajo);
printf("\n\t* Nombre y Apellido: %s", empleadoActual.nombreApellido);
printf("\n\t* Sueldo (en pesos): %.2f", empleadoActual.sueldo);
i++;
}
fclose(archivoEmpleados);
}
/*
Esta funcion no elimina en si la linea que pertenezca al empleado
Sino mas bien, la omitiria cuando la lea, escribiendo un archivo nuevo con el mismo nombre
De esa forma, estariamos haciendo lo mismo
*/
void eliminarEmpleadoPorLegajo(Empleado empleados[], int legajo, int cantidadEmpleados, int *eliminados)
{
// Intentamos abrir el archivo y verificamos si no es un puntero nulo
FILE * archivoEmpleados = fopen("empleados.txt", "r");
// Creamos un nuevo archivo para escribir los datos
FILE * nuevoArchivoEmpleados = fopen("empleados2.txt", "w");
if(archivoEmpleados != NULL)
{
int i = 0;
while (!feof(archivoEmpleados) && i < cantidadEmpleados)
{
char datosSinParsear[50] = "";
Empleado empleadoActual;
// Recibimos los datos y los parseamos
fgets(datosSinParsear, 50, archivoEmpleados);
empleadoActual = parsearEmpleado(datosSinParsear, 50);
/*
Cuando no coincida el legajo, escribe
Si es que llega a coincidir (justamente ese debemos eliminar), no lo escribimos,
simplemente, hacemos una iteración y continuamos el bucle
*/
if (empleadoActual.legajo != legajo)
{
fprintf(nuevoArchivoEmpleados, "%d;%s;%.2f\n", empleadoActual.legajo, empleadoActual.nombreApellido, empleadoActual.sueldo);
i++;
}
else
{
i++;
continue;
};
}
fclose(archivoEmpleados);
fclose(nuevoArchivoEmpleados);
remove("empleados.txt");
rename("empleados2.txt", "empleados.txt");
eliminarEmpleadoVectorPorLegajo(empleados, legajo, cantidadEmpleados, &eliminados);
*eliminados = *eliminados + 1;
printf("\nEmpleado con legajo numero %d eliminado exitosamente", legajo);
}
// Si el archivo no existe o no lo encuentra
else
{
printf("\nImposible eliminar al empleado\nEl archivo \"empleados.txt\" no existe o no se encuentra en la ruta actual");
exit(-1);
}
}
void eliminarEmpleadoVectorPorLegajo(Empleado empleados[], int legajo, int cantidadEmpleados, int *eliminados)
{
int posicionDelElemento = -1;
for (int i = 0; i < cantidadEmpleados; i++)
{
if(empleados[i].legajo == legajo)
{
posicionDelElemento = i;
i = cantidadEmpleados;
}
}
for(int i = posicionDelElemento - 1; i<cantidadEmpleados-1; i++)
{
empleados[i] = empleados[i + 1];
}
cantidadEmpleados--;
}
void menu(Empleado empleados[], int cantidadEmpleados)
{
int sigue = 1;
int eliminados = 0;
int cantidadEmpleadosVar = 0;
printf("\nMenu Empleados\n");
printf("\nOpciones:\n");
printf("\n\t1. Listar los empleados");
printf("\n\t2. Agregar un empleado");
printf("\n\t3. Eliminar un empleado");
printf("\n\t4. Salir");
do
{
int opcion;
int legajo;
printf("\nIngrese opcion > ");
scanf("%d", &opcion);
switch (opcion)
{
case 1:
printf("\nMostrando empleados cargados");
mostrarEmpleadosDesdeArchivo(cantidadEmpleados, eliminados);
break;
case 2:
printf("\nAgregar un empleado:");
printf("\nCuantos empleados desea cargar? > ");
scanf("%d", &cantidadEmpleadosVar);
cargarEmpleadosPorTeclado(empleados, cantidadEmpleadosVar);
break;
case 3:
printf("\nEliminando un empleado:");
printf("\nIngrese el numero de legajo del empleado a eliminar > ");
scanf("%d", &legajo);
eliminarEmpleadoPorLegajo(empleados, legajo, cantidadEmpleados, &eliminados);
break;
case 4:
sigue = 0;
break;
default:
printf("\nLa opcion \"%d\" no es valida, ingrese otra vez\n\n", opcion);
continue;
break;
}
} while (sigue);
}
And the empleados.txt file is the following:
555666;Leandro;80041.00
232433;Juan;80945.00
234443;Antonio;90485.00
119304;Manuel;102943.00
The output is:
Code output linked on imgur
Does anyone know what this error could be?
There are many issues in your code, here are some important ones:
you must not use gets(): read Why is the gets function so dangerous that it should not be used?
you should test the return value of fgets() to determine if a line was read or if end of file has been reached.
using feof() for this purpose as you do is incorrect. You should read Why is “while( !feof(file) )” always wrong?
you should always test for fopen() success before calling any stream function with the FILE pointer.
Also use more spaces for indentation, 4 is recommended for readability.
I'm trying to read a bunch of information about a player from a binary file in c through the following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// structure joueur
typedef struct Joueur {
char nom[20];
int num_lieu;
int liste_objet[10];
}Joueur;
// question a
void sauvegarder_jeu(char* nom_partie, Joueur* joueur) {
// ouverture du fichier
FILE *flot;
flot = fopen(nom_partie, "wb");
if (flot == NULL) {
printf("Erreur dans l'ouverture du fichier!\n");
return;
}
// écriture du nom du joueur
fwrite(joueur->nom, sizeof(joueur->nom), 1, flot);
// écriture du numero du lieu
fwrite(&(joueur->num_lieu), sizeof(joueur->num_lieu), 1, flot);
// écriture de la liste des objets
fwrite(joueur->liste_objet, sizeof(joueur->liste_objet), 1, flot);
// fermeture du fichier
fclose(flot);
}
// question b
void charger_jeu(char* nom_partie, char* nom, int* num_lieu, int* liste_objet) {
// ouverture du fichier
FILE *flot;
flot = fopen(nom_partie, "rb");
if (flot == NULL) {
printf("Erreur dans l'ouverture du fichier!\n");
return;
}
// joueur temp pour sizeof
Joueur *temp = (Joueur*)malloc(sizeof(Joueur));
// lecture du nom du joueur
fread(nom, sizeof(temp->nom), 1, flot);
// écriture du numero du lieu
fread(&num_lieu, sizeof(temp->num_lieu), 1, flot);
// écriture de la liste des objets
fread(liste_objet, sizeof(temp->liste_objet), 1, flot);
// suppression du joueur temporaire
free(temp);
// fermeture du fichier
fclose(flot);
}
int main() {
// variables
char *nom_partie = "save.sve";
int i;
int* num_lieu_lecture;
int* liste_objet_lecture;
char* nom_lecture;
// creation d'un joueur qui possede tous les objets
Joueur *j1 = (Joueur*)malloc(sizeof(Joueur));
strcpy(j1->nom, "Omar");
j1->num_lieu = 12;
for (i = 0; i < 10; i++) {
j1->liste_objet[i] = 1;
}
// sauvegarde de la partie
sauvegarder_jeu(nom_partie, j1);
printf("Sauvegarde terminee!\n");
// lecture de la partie
charger_jeu(nom_partie, nom_lecture, num_lieu_lecture, liste_objet_lecture);
printf("Chargement terminee!\n");
// affichage des donnees de la partie
printf("%s\n", nom_lecture);
printf("%d\n", *num_lieu_lecture);
for (i = 0; i < 10; i++) {
printf("liste_objet[%d] = %d\n", i, liste_objet_lecture[i]);
}
// liberation de la memoire
free(j1);
return 0;
}
The function "sauvegarder_jeu()" writes the player's data into a binary file, and the "charger_jeu()" is supposed to read that data and store into variables that I would print out.
The output, where all the values are correct expect for the "num_lieu_lecture" value:
Omar
32759
liste_objet[0] = 1
liste_objet[1] = 1
liste_objet[2] = 1
liste_objet[3] = 1
liste_objet[4] = 1
liste_objet[5] = 1
liste_objet[6] = 1
liste_objet[7] = 1
liste_objet[8] = 1
liste_objet[9] = 1
I don't know where the problem stems from.
The variables you're passing to charger_jeu() do not need to be pointers. num_liste_objet should be int, and liste_objet_lecture and nom_lecture should be arrays.
Then you should pass the address of num_liste_objet to charger_jeu(), so it will update the variable. In charger_jeu() you don't need to use & before num_lieu because it's already a pointer.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// structure joueur
typedef struct Joueur {
char nom[20];
int num_lieu;
int liste_objet[10];
}Joueur;
// question a
void sauvegarder_jeu(char* nom_partie, Joueur* joueur) {
// ouverture du fichier
FILE *flot;
flot = fopen(nom_partie, "wb");
if (flot == NULL) {
printf("Erreur dans l'ouverture du fichier!\n");
return;
}
// écriture du nom du joueur
fwrite(joueur->nom, sizeof(joueur->nom), 1, flot);
// écriture du numero du lieu
fwrite(&(joueur->num_lieu), sizeof(joueur->num_lieu), 1, flot);
// écriture de la liste des objets
fwrite(joueur->liste_objet, sizeof(joueur->liste_objet), 1, flot);
// fermeture du fichier
fclose(flot);
}
// question b
void charger_jeu(char* nom_partie, char* nom, int* num_lieu, int* liste_objet) {
// ouverture du fichier
FILE *flot;
flot = fopen(nom_partie, "rb");
if (flot == NULL) {
printf("Erreur dans l'ouverture du fichier!\n");
return;
}
// joueur temp pour sizeof
Joueur *temp = (Joueur*)malloc(sizeof(Joueur));
// lecture du nom du joueur
fread(nom, sizeof(temp->nom), 1, flot);
// écriture du numero du lieu
fread(num_lieu, sizeof(temp->num_lieu), 1, flot);
// écriture de la liste des objets
fread(liste_objet, sizeof(temp->liste_objet), 1, flot);
// suppression du joueur temporaire
free(temp);
// fermeture du fichier
fclose(flot);
}
int main() {
// variables
char *nom_partie = "save.sve";
int i;
int num_lieu_lecture;
int liste_objet_lecture[10];
char nom_lecture[20];
// creation d'un joueur qui possede tous les objets
Joueur *j1 = (Joueur*)malloc(sizeof(Joueur));
strcpy(j1->nom, "Omar");
j1->num_lieu = 12;
for (i = 0; i < 10; i++) {
j1->liste_objet[i] = 1;
}
// sauvegarde de la partie
sauvegarder_jeu(nom_partie, j1);
printf("Sauvegarde terminee!\n");
// lecture de la partie
charger_jeu(nom_partie, nom_lecture, &num_lieu_lecture, liste_objet_lecture);
printf("Chargement terminee!\n");
// affichage des donnees de la partie
printf("%s\n", nom_lecture);
printf("%d\n", *num_lieu_lecture);
for (i = 0; i < 10; i++) {
printf("liste_objet[%d] = %d\n", i, liste_objet_lecture[i]);
}
// liberation de la memoire
free(j1);
return 0;
}
I have some problems with my code. I want to load a file (i can do it in "cargar" function), i have my menu, my "show list" function (mostrar_lista) and my "add function" (anadir_elemento) but i have problems with guardar (my save function).
When I use my save function (guardar) i can't save anything, my file "records.txt" just collapses and i have a file with 700.000 Kbytes.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct unDisco{
char titulo[100];
char artista[100];
short fecha;
char formato[50];
float precio;
struct unDisco *siguiente;
};
struct unDisco *primero, *ultimo;
void cargar(){
FILE *discoteca;
discoteca = fopen("records.txt","r");
if (discoteca==NULL){
return ;
}else{
char ayuda, titulo[100], artista[100], formato[50];
int cont=0, k, fecha, n;
float precio;
while((ayuda=fgetc(discoteca))!=EOF){
if (ayuda=='\n'){
cont++;
}
}
rewind(discoteca);
char linea[cont][1024];
for (k=0;k<cont;k++){
fgets(linea[k],1023,discoteca);
struct unDisco *disco=(struct unDisco *)malloc(sizeof(struct unDisco));
sscanf(linea[k]," %s %s %i %s %f", titulo,artista,&fecha,formato,&precio);
strcpy(disco->titulo, titulo);
strcpy(disco->artista, artista);
strcpy(disco->formato, formato);
disco->fecha=fecha;
disco->precio=precio;
if (primero==NULL) {
primero = disco;
ultimo = disco;
}
else {
ultimo->siguiente = disco;
ultimo = disco;
}
}
}
fclose(discoteca);
return ;
}
void mostrar_menu() {
printf("\n\nMenú:\n=====\n\n");
printf("1.- Añadir elementos\n");
printf("2.- Borrar elementos\n");
printf("3.- Mostrar lista\n");
printf("4.- Salir\n\n");
printf("Escoge una opción: ");fflush(stdout);
}
void anadir_elemento() {
struct unDisco *disco;
int data;
float prezo;
char titulo[100],artista[100],formato[50];
//reservamos memoria para el nuevo elemento
disco = (struct unDisco *) malloc (sizeof(struct unDisco));
printf("\nTitulo: "); fflush(stdout);
fscanf(stdin," %s",titulo);
printf("Artista: "); fflush(stdout);
fscanf(stdin," %s",artista);
printf("Fecha: "); fflush(stdout);
fscanf(stdin," %i",&data);
printf("Formato: "); fflush(stdout);
fscanf(stdin," %s",formato);
printf("Precio: "); fflush(stdout);
fscanf(stdin," %f",&prezo);
strcpy(disco->titulo, titulo);
strcpy(disco->artista, artista);
strcpy(disco->formato, formato);
disco->fecha=data;
disco->precio=prezo;
// el campo siguiente va a ser NULL por ser el último elemento de la lista
disco->siguiente = NULL;
// ahora metemos el nuevo elemento en la lista. lo situamos al final de la lista
//comprobamos si la lista está vacía. si primero==NULL es que no hay ningún elemento en la lista. también vale ultimo==NULL
if (primero==NULL) {
printf( "Primer elemento\n");
primero = disco;
ultimo = disco;
}
else {
// el que hasta ahora era el último tiene que apuntar al nuevo
ultimo->siguiente = disco;
// hacemos que el nuevo sea ahora el último
ultimo = disco;
}
}
void mostrar_lista() {
struct unDisco *auxiliar; // lo usamos para recorrer la lista
int i;
i=0;
auxiliar = primero;
printf("\nMostrando la lista completa:\n");
while (auxiliar!=NULL) {
printf( "Titulo: %s, Artista: %s, Fecha: %i, Formato: %s, Precio: %.2f",
auxiliar->titulo,auxiliar->artista,auxiliar->fecha,auxiliar->formato,auxiliar->precio);
auxiliar = auxiliar->siguiente;
i++;
}
if (i==0) printf( "\nLa lista está vacía!!\n" );
}
void guardar(){
FILE *discoteca;
struct unDisco *disco;
discoteca=fopen("records.txt","w");
while(disco->siguiente!=NULL){
fprintf(discoteca,"%s %s %i %s %.2f\n",
disco->titulo, disco->artista, disco->fecha, disco->formato, disco->precio);
}
fclose(discoteca);
}
int main(){
char opcion;
cargar();
primero = (struct unDisco *) NULL;
ultimo = (struct unDisco *) NULL;
do {
mostrar_menu();
fscanf(stdin," %c",&opcion);
switch ( opcion ) {
case '1': anadir_elemento();
break;
case '2': printf("No disponible todavía!\n");
break;
case '3': mostrar_lista(primero);
break;
case '4':
guardar();
exit( 1 );
break;
default: printf( "Opción no válida\n" );
break;
}
} while (opcion!='4');
return 0;
}
it seems logical that guardar receives the unDisco in parameter, something like
void guardar(struct unDisco *disco){
FILE *discoteca = fopen("records.txt","w");
while(disco != NULL) { /* <<< test changed */
fprintf(discoteca,"%s %s %i %s %.2f\n",
disco->titulo, disco->artista,
disco->fecha, disco->formato,
disco->precio);
disco = disco->siguiente; /* <<< added */
}
fclose(discoteca);
}
I'm working in a WPF (c#) application and need to use thread in some process. but "InvokeRequired" dont work.
I look this answer but I cant get work.
This is my code:
private void CambiarProgreso(string texto, int valor)
{
if (this.InvokeRequired) //preguntamos si la llamada se hace desde un hilo
{
//si es así entonces volvemos a llamar a CambiarProgreso pero esta vez a través del delegado
//instanciamos el delegado indicandole el método que va a ejecutar
CambiarProgresoDelegado delegado = new CambiarProgresoDelegado(CambiarProgreso);
//ya que el delegado invocará a CambiarProgreso debemos indicarle los parámetros
object[] parametros = new object[] { texto, valor };
//invocamos el método a través del mismo contexto del formulario (this) y enviamos los parámetros
this.Invoke(delegado, parametros);
}
else
{
//en caso contrario, se realiza el llamado a los controles
lblProgreso.Content = texto;
PrbProgreso.Value = valor;
}
}
delegate void CambiarProgresoDelegado(string texto, int valor);
Thank you ver much!
This resolve my problem.
Thanks.
private void CambiarProgreso(string texto, int valor)
{
if (!this.Dispatcher.CheckAccess()) //preguntamos si la llamada se hace desde un hilo
{
//si es así entonces volvemos a llamar a CambiarProgreso pero esta vez a través del delegado
//instanciamos el delegado indicandole el método que va a ejecutar
//CambiarProgresoDelegado delegado = new CambiarProgresoDelegado(CambiarProgreso);
//ya que el delegado invocará a CambiarProgreso debemos indicarle los parámetros
object[] parametros = new object[] { texto, valor };
//invocamos el método a través del mismo contexto del formulario (this) y enviamos los parámetros
this.Dispatcher.Invoke(new CambiarProgresoDelegado(CambiarProgreso), parametros);
}
else
{
//en caso contrario, se realiza el llamado a los controles
lblProgreso.Content = texto;
PrbProgreso.Value = valor;
}
}