Autor
|
Tema: estructuras y lectura de archivos en C (Leído 2,608 veces)
|
michellcrh
Desconectado
Mensajes: 14
|
:-\Hola tengo que realizar un programa haciendo uso de estructuras dinamicas y lectura de archivos, pero no puedo hacer correctamente la extracción de los archivos y guardarlos en arreglos. Solo guarda el nombre y la cantidad, pero el autor y el precio no. Este es mi código: #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct{ char *nombre; char *autor; int cantidad; int precio; }libros; libros *l; void menu(); void vaciar(char temp[]); void copiarNombre(char temp[],int i); void copiarAutor(char temp[],int i); int main(){ char temp[50],aux; int contador = 0; FILE *fichero; fichero = fopen("libros.txt","rt"); if(fichero == NULL){ printf("No se ha encontrado el documento\n"); return 0; } contador++; } l = (libros *)malloc(contador *sizeof(libros )); if(l == NULL){ printf("NO SE HA PODIDO RESERVAR LA MEMORIA\n"); return 0; } for(int i =0;!feof(fichero ); i ++){ vaciar(temp); aux = '0'; for(int j=0; aux != ','; j++ ){ if(aux != ','){ temp[j] = aux; } } copiarNombre(temp,i); copiarAutor(temp,i); l [i ]. cantidad = atoi(temp ); l [i ]. precio = atoi(temp ); printf("Precio: %d\n",l [i ]. precio); } return 0; } void menu(){ int opc; printf("\t\t\tLIBRERIA FI\n\n"); printf("1. Leer inventario inicial\n"); printf("2. Mostrar inventario de existencias\n"); printf("4. Informe de ventas\n"); printf(" \nIngrese el numero correspondiente a la operacion que desea realizar: "); } void vaciar(char temp[]){ for(int i=0; i<50; i++){ temp[i] = '\0'; } } void copiarNombre(char temp[],int i){ int longitud; l [i ]. nombre = (char*)malloc(longitud *sizeof(char)); if(l[i].nombre == NULL){ printf("No se ha podido reservar memoria\n"); return 0; } } void copiarAutor(char temp[],int i){ int longitud; l [i ]. autor = (char*)malloc(longitud *sizeof(char)); if(l[i].autor == NULL){ printf("No se ha podido reservar memoria\n"); return 0; } }
mi archivo de texto es el siguiente: La casa de los espiritus,Isabel Allende,5,345 La Metamorfosis,Franz Kafka,3,560 La Odisea,Homero,7,200 El Principito,Antoine de Saint-Exupery,2,499 El Laberinto de la Soledad,Octavio Paz,1,150 El tunel,Ernesto Sabato,3,100 Los miserables,Victor Hugo,5,290 Cuentos de amor de locura y de muerte,Horacio Quiroga,4,563 El amor en lo tiempos de colera,Gabriel Garcia Marquez,6,218 MOD: Utiliza las etiquetas de Código GeSHi para los fragmentos de código
|
|
« Última modificación: 30 Mayo 2020, 08:26 am por YreX-DwX »
|
En línea
|
|
|
|
K-YreX
|
El problema principal es la separación que estás haciendo en tokens o partes. Buscas hasta la primera coma (,) para localizar el nombre del libro pero de seguido guardas el nombre del autor también sin haber buscado hasta la siguiente coma. Por lo tanto, el nombre del libro y el autor siempre son la misma cadena. A partir de ahí ya se descuadran todos los cálculos (que tampoco entiendo esos fgets() con longitud 4 y 5...) y se guarda todo mal. Además otro problema es que la cadena que usas para guardar cada línea del fichero temporalmente tiene una longitud de 50 y hay líneas que superan ese número de caracteres por lo que los caracteres que no entran en una línea, se leen en la siguiente. Otro otro tema importante cuando se trabaja con memoria dinámica es que esa memoria tienes que liberarla manualmente usando free(). Y otro tema es usar return para salir en caso de error. En la función main() se puede hacer porque de un return acaba el programa pero en otras funciones auxiliares, llamar a return lo que hace es devolver el control a la función que llamó a esta. Es más correcto utilizar exit(). Además el valor 0 se suele asociar a que todo ha finalizado correctamente. Para errores es mejor usar -1. En conjunto: exit(-1). Otros consejos son: - Utilizar una constante para la longitud de la cadena que te permita modificarlo rápidamente sin tener que ir mirando por todo el código.
- No utilizar variables globales, como en tu caso el puntero l.
- Para separar una cadena en base a un patrón o varios tienes la función strtok().
- Para "vaciar" una cadena no es necesario poner '\0' a todas sus posiciones. Basta con hacerlo en la posición 0.
Te dejo otra forma de hacerlo con las modificaciones antes mencionadas: #include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 100 typedef struct { char *nombre; char *autor; int cantidad; int precio; } Libro; void liberarMemoria(Libro *libros, int numeroLibros){ for(int i = 0; i < numeroLibros; ++i){ } } void guardarLibro(Libro *libros, char *temporal, int numeroLibros){ char *token = strtok(temporal , ","); libros [numeroLibros -1]. nombre = (char*)malloc((strlen(token )+1) * sizeof(char)); strcpy(libros [numeroLibros -1]. nombre, token ); libros [numeroLibros -1]. autor = (char*)malloc((strlen(token )+1) * sizeof(char)); strcpy(libros [numeroLibros -1]. autor, token ); libros [numeroLibros -1]. cantidad = atoi(token ); libros [numeroLibros -1]. precio = atoi(token );} void mostrarLibros(Libro *libros, int numeroLibros){ for(int i = 0; i < numeroLibros; ++i){ printf("***** INFORMACION LIBRO %d *****\n", i +1); printf("Nombre: %s\n", libros [i ]. nombre); printf("Autor: %s\n", libros [i ]. autor); printf("Cantidad: %d\n", libros [i ]. cantidad); printf("Precio: %d\n", libros [i ]. precio); } } int main(){ Libro *libros = NULL; char temporal[SIZE]; FILE *fichero = fopen("libros.txt", "r"); int numeroLibros = 0; while(fgets(temporal , SIZE , fichero )) { ++numeroLibros; libros = (Libro *)realloc(libros , numeroLibros * sizeof(Libro )); guardarLibro(libros, temporal, numeroLibros); } mostrarLibros(libros, numeroLibros); liberarMemoria(libros, numeroLibros); return 0; }
PD: Cuando vayas a insertar código utiliza etiquetas de Código GeSHi y selecciona el lenguaje que corresponda a tu código. En tu mensaje anterior ya te las he incluido yo pero para otra ocasión. PD 2: Aunque no es relevante, el menú que tienes no funciona. Si vas a pedir una opción tendrás que devolverla con un return.
|
|
|
En línea
|
cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
|
|
|
michellcrh
Desconectado
Mensajes: 14
|
Te lo agradezco mucho
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
foto lectura, y lectura veloz, scanning y otros metodos de lectura rapida....
Foro Libre
|
Kase
|
3
|
13,044
|
4 Febrero 2014, 08:47 am
por camilo_
|
|
|
lectura de archivos
Software
|
mapers
|
2
|
2,264
|
19 Enero 2011, 11:56 am
por palomitero
|
|
|
Estructuras y archivos en c++
Programación C/C++
|
Luifs
|
5
|
3,246
|
8 Junio 2013, 02:27 am
por rir3760
|
|
|
Lectura de archivos log
Programación C/C++
|
mauricioPaz19922
|
2
|
2,092
|
15 Noviembre 2014, 17:35 pm
por Miky Gonzalez
|
|
|
Lectura de archivos C++
Programación C/C++
|
Azdepredador
|
3
|
2,229
|
28 Enero 2016, 16:35 pm
por Carlos D. Alvarez
|
|