Autor
|
Tema: Grabar estructura en archivo [lenguaje C] [Windows 7] (Leído 6,241 veces)
|
DanielPy
Desconectado
Mensajes: 145
|
Hola gente. Nuevamente con dudas que no logro resolver con el manual ni con consultas en la web (con este último tal vez lo lograría pero nunca encuentro cosas tan avanzadas como las de este foro, gracias al gran conocimiento de los que responden).- Mi consulta es, la única manera de grabar los datos en disco es con fprintf y detallando uno por uno los campos de la estructura o hay alguna manera de hacerlo más conciso, realmente ¿si la estructura tiene 20 campos hay que detallarlo uno por uno?- Por último si alguien tiene mucho tiempo y desea darme alguna sugerencia para mejorar el código, Danielito agradecido.- #include <stdio.h> #include <windows.h> #include <string.h> typedef struct{ int orden; char nombre[30]; char apellido[30]; char direccion[30]; int numCalle; char ciudad[30]; char provincia[30]; }Cliente; void mosDtos(Cliente *ptrCliente); void ingDtos(Cliente *ptrCliente); void opciones(Cliente *ptrCliente); void graDtos(Cliente *ptrCliente); int main(void){ FILE *ptrCte; Cliente datos = {0, "\0", "\0", "\0", 0, "\0", "\0"}; if(( ptrCte = fopen( "archivo.txt", "w" )) == NULL ){ } else{ ingDtos(&datos); } return 0; } void mosDtos(Cliente *ptrCliente){ printf("\n\n == Introduzca datos del cliente \"Ningun campo puede permanecer vacio\" =="); printf( "\n\n =========================================================================\n" ); printf("\n Orden...............: %d", ptrCliente ->orden ); printf("\n Nombre..............: %s", ptrCliente ->nombre ); printf("\n Apellido............: %s", ptrCliente ->apellido ); printf("\n Direccion...........: %s", ptrCliente ->direccion ); printf("\n Altura de la calle..: %d", ptrCliente ->numCalle ); printf("\n Ciudad..............: %s", ptrCliente ->ciudad ); printf("\n Provincia...........: %s", ptrCliente ->provincia ); printf( "\n\n =========================================================================\n" ); } void ingDtos(Cliente *ptrCliente){ int ok, ch; char *p = NULL; do{ mosDtos(ptrCliente); printf("\n Orden...............: "); ok = scanf("%d", &ptrCliente ->orden ) == 1 && ptrCliente ->orden >= 1; while ((ch = getchar()) != EOF && ch != '\n'); }while(!ok); do{ mosDtos(ptrCliente); printf("\n Nombre..............: "); fgets(ptrCliente ->nombre , 30, stdin ); if((p =strchr(ptrCliente ->nombre , '\n'))){ *p='\0'; } else{ while((ch = getchar()) !='\n' && ch !=EOF ); } ok = strlen(ptrCliente ->nombre ); }while(!ok); do{ mosDtos(ptrCliente); printf("\n Apellido............: "); fgets(ptrCliente ->apellido , 30, stdin ); if((p =strchr(ptrCliente ->apellido , '\n'))){ *p='\0'; } else{ while((ch = getchar()) !='\n' && ch !=EOF ); } ok = strlen(ptrCliente ->apellido ); }while(!ok); do{ mosDtos(ptrCliente); printf("\n Direccion...........: "); fgets(ptrCliente ->direccion , 30, stdin ); if((p =strchr(ptrCliente ->direccion , '\n'))){ *p='\0'; } else{ while((ch = getchar()) !='\n' && ch !=EOF ); } ok = strlen(ptrCliente ->direccion ); }while(!ok); do{ mosDtos(ptrCliente); printf("\n Altura de la calle..: "); ok = scanf( "%d", &ptrCliente ->numCalle ) == 1 && ptrCliente ->numCalle >= 1; while ((ch = getchar()) != EOF && ch != '\n'); }while(!ok); do{ mosDtos(ptrCliente); printf("\n Ciudad..............: "); fgets(ptrCliente ->ciudad , 30, stdin ); if((p =strchr(ptrCliente ->ciudad , '\n'))){ *p='\0'; } else{ while((ch = getchar()) !='\n' && ch !=EOF ); } ok = strlen(ptrCliente ->ciudad ); }while(!ok); do{ mosDtos(ptrCliente); printf("\n Provincia...........: "); fgets(ptrCliente ->provincia , 30, stdin ); if((p =strchr(ptrCliente ->provincia , '\n'))){ *p='\0'; } else{ while((ch = getchar()) !='\n' && ch !=EOF ); } ok = strlen(ptrCliente ->provincia ); }while(!ok); mosDtos(ptrCliente); opciones(ptrCliente); } void opciones(Cliente *ptrCliente){ int opcion, ok; char ch; do{ mosDtos(ptrCliente); printf("\n ========= Opciones ========="); printf("\n 1 - Grabar en disco."); printf("\n 2 - Introducir nuevamente los datos."); printf("\n\n Ingrece opci%cn....: ", 162); ok = scanf("%d", &opcion ) == 1 && opcion >= 1 && opcion <= 3; while ((ch = getchar()) != EOF && ch != '\n'); }while(!ok); if(opcion == 1){ graDtos(ptrCliente); } else if(opcion == 2){ ptrCliente->orden = 0; strcpy(ptrCliente ->nombre , "\0"); strcpy(ptrCliente ->apellido , "\0"); strcpy(ptrCliente ->direccion , "\0"); ptrCliente->numCalle = 0; strcpy(ptrCliente ->ciudad , "\0"); strcpy(ptrCliente ->provincia , "\0"); mosDtos(ptrCliente); ingDtos(ptrCliente); } } void graDtos(Cliente *ptrCliente){ }
Una cosita más, no desconozco que las validaciones no son del todo eficiente, pero eso lo soluciono luego.- Saludos y gracias por el tiempo. Daniel
|
|
|
En línea
|
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
|
|
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
En memoria, una estructura que yo sepa se guarda en un bloquede memoria, contiguo. Por tanto, bastaría hacer un cast a char*.
Pero yo no haría eso, principalmente, porque una estructura puede guardar punteros, y porque puede ser más problemático.
Basta hacer una función que serialice la estructura. Sean 1, 2 o 10 campos, la función no se va a alargar, no hay razón para evitarla.
|
|
|
En línea
|
|
|
|
BloodSharp
Desconectado
Mensajes: 812
¡ Hiperfoco !
|
Mi consulta es, la única manera de grabar los datos en disco es con fprintf y detallando uno por uno los campos de la estructura o hay alguna manera de hacerlo más conciso, realmente ¿si la estructura tiene 20 campos hay que detallarlo uno por uno? No, para esciribir toda una estructura de una tenés fwrite... B#
|
|
|
En línea
|
|
|
|
DanielPy
Desconectado
Mensajes: 145
|
Hola. ivancea96, como conozco que no te gusta demasiado poner código no te voy a pedir que lo hagas, como siempre y seguramente la tuya es una muy buena solución, me voy a documentar sobre “Basta hacer una función que serialice la estructura. Sean 1, 2 o 10 campos, la función no se va a alargar, no hay razón para evitarla.” , no tengo conocimientos sobre el particular.- BloodSharp, voy a practicar con la función que propones.- Gracias a los 2 por el tiempo.- Saludos. Daniel
|
|
|
En línea
|
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
|
|
|
|
DanielPy
Desconectado
Mensajes: 145
|
Hola BloodSharp. Si te toparas en un caso como el mío me podrías decir como lo solucionarías, el caso es que estoy buscando desde que ivancea96 me sugirió serealizar los campos de la estructura y no encuentro ni un mísero ej. o por lo menos al alcance de mis conocimientos, espero puedas(an) ayudarme.
Saludos. Daniel
|
|
|
En línea
|
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
|
|
|
BloodSharp
Desconectado
Mensajes: 812
¡ Hiperfoco !
|
Hola BloodSharp. Si te toparas en un caso como el mío me podrías decir como lo solucionarías, el caso es que estoy buscando desde que ivancea96 me sugirió serealizar los campos de la estructura y no encuentro ni un mísero ej. o por lo menos al alcance de mis conocimientos, espero puedas(an) ayudarme.
Saludos. Daniel Mmm, en realidad depende de como uno lo quiera grabar los datos y la cantidad de estructuras de objetos quieras guardar... En mi caso yo primero cifraría los datos de la estructura con una clave (cosa que en realidad es opcional y para complicar la lectura de como están guardados los datos, sobretodo en los strings, dado a que si no están cifrados aparecen tal cúal están como si fuera en texto plano) y luego escribiría la estructura entera cifrada. Ejemplo usando tu código: FILE *ptrCte;//Archivo ya abierto int graDtos(Cliente *ptrCliente) { return fwrite(ptrCliente ,sizeof(Cliente ),1,ptrCte ); } int leerDatos(Cliente *ptrCliente) { return fread(ptrCliente ,sizeof(Cliente ),1,ptrCte ); } char *szClave="unaClave"; int graDtosCifrados(Cliente *ptrCliente) { Cliente clienteCifrado; memcpy(&clienteCifrado ,ptrCliente ,sizeof(Cliente )); //No cifro la estructura original por si la necesito luego RutinaParaCifrar (&clienteCifrado ,sizeof(Cliente ),szClave ,strlen(szClave )); return fwrite(clienteCifrado ,sizeof(Cliente ),1,ptrCte ); } int leerDatosCifrados(Cliente *ptrCliente) { int bytesleidos; Cliente clienteDescifrado; byteleidos =fread(clienteDescifrado ,sizeof(Cliente ),1,ptrCte ); RutinaParaCifrar (&clienteDescifrado ,sizeof(Cliente ),szClave ,strlen(szClave )); memcpy(ptrCliente ,&clienteDescifrado ,sizeof(Cliente )); return bytesleidos; }
B#
|
|
|
En línea
|
|
|
|
DanielPy
Desconectado
Mensajes: 145
|
Hola BloodSharp. Muchas gracias por el código.- Te explico, como por el momento me resultaba muy difícil entender tú código y para no molestarte tanto me puse a buscar nuevamente en internet y encontré más de un video que ponían ejemplos con estructuras con campos de diferentes tipos, pude implementarlos y funcionan a la perfección, evidentemente el programa que puse es un poco largo y no supe explicarme lo suficiente.- Bueno retomando el nuevo código les pido una manito para solucionar 2 cositas que me quedan pendiente: La primera es ¿Cómo puedo hacer para imprimir el último dato ingresado? Es que quiero ingresar "matricula" en orden, o sea 1,2,3,4,5,6,7… para ello necesito ver en pantalla el último ingreso, obviamente sería interesante que este campo sea de sólo lectura y que se rellenara sólo con la última matricula + 1, pero bueno para mis conocimiento sobre archivos en C con que me muestre en pantalla el último es suficiente.- Lo último es un inconveniente con el bucle while, siempre me duplica el último dato.- Esta vez parece todo más sencillo y fácil de entender.- #include <stdio.h> struct registro{ char nombre[30]; int matricula; }est; int main(void){ FILE *ptrEst; int ch; if( (ptrEst = fopen( "ingles.txt" , "a+" )) == NULL ){ printf( "\n\n ERROR, no se pudo abrir el archivo..." ); } else{ // fread(&est, sizeof(est), 1, ptrEst); // printf( "\n\n Ultimo ingreso....: %d - %s \n", est.matricula, est.nombre ); printf( "\n\n Nombre.........:"); printf( "\n Matricula......:" ); scanf( "%d", &est. matricula ); while ((ch = getchar()) != EOF && ch != '\n'); fwrite(&est , sizeof(est ), 1, ptrEst ); printf( "\n\n Listado completo\n" ); fread(&est , sizeof(est ), 1, ptrEst ); printf( " %d - %s \n", est. matricula, est. nombre ); } } return 0; }
Gracias ivancea96 por tú ayuda.-Saludos. Daniel
|
|
|
En línea
|
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
|
|
|
BloodSharp
Desconectado
Mensajes: 812
¡ Hiperfoco !
|
//Asumiendo que tenés al menos una entrada de estructura ya previamente guardada... int ultimaMatricula; fseek(ptrEst ,(-1)*sizeof(int), SEEK_END ); fread(&ultimaMatricula ,sizeof(int),1,ptrEst );
printf( "\n\n Listado completo\n" ); fread(&est , sizeof(est ), 1, ptrEst ); printf( " %d - %s \n", est. matricula, est. nombre ), fread(&est , sizeof(est ), 1, ptrEst );
B#
|
|
|
En línea
|
|
|
|
DanielPy
Desconectado
Mensajes: 145
|
Hola. No me funciona ninguno de los 2 códigos, si los utilizo, el primero no me deja agregar registros, pero no desesperemos, teniendo las funciones correctas (que seguramente lo son) voy a buscar en la web para hacer que funcione.-
Saludos. Daniel
|
|
|
En línea
|
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Ayuda con metodos de un archivo (estructura de datos)
Programación General
|
crifesma
|
0
|
2,003
|
3 Junio 2011, 03:02 am
por crifesma
|
|
|
Grabar datos a DVDs sin perder estructura de carpetas
Software
|
pisagatos
|
2
|
6,022
|
19 Octubre 2011, 10:17 am
por el-brujo
|
|
|
Castear estructura en un archivo.c distinto al main
Programación C/C++
|
Fabi0lo
|
3
|
2,730
|
20 Noviembre 2012, 23:29 pm
por rir3760
|
|
|
problemilla con estructura y archivo txt
Programación C/C++
|
MessageBoxA
|
5
|
3,134
|
10 Junio 2014, 17:40 pm
por rir3760
|
|
|
Descifrar estructura de archivo con formato propietario
Ingeniería Inversa
|
marceloarguello700
|
2
|
2,367
|
19 Agosto 2014, 18:39 pm
por marceloarguello700
|
|