• Viernes 8 de Noviembre de 2024, 16:02

Autor Tema:  Parametros genericos....  (Leído 2872 veces)

Luciano9

  • Miembro activo
  • **
  • Mensajes: 25
    • Ver Perfil
Parametros genericos....
« en: Viernes 8 de Mayo de 2009, 21:04 »
0
&ArchHola, antes que nada me presento. Me llamo Luciano, estudio Analisis de Sistemas y soy nuevo en el foro.
Tengo una duda sobre lo siguiente:

Estoy haciendo 1 proyecto que maneja archivos.
Tengo varios cpps con sus respectivos .h de los cuales uno se llama "ARCH.CPP" y tiene su "ARCH.H".
Estos tienen las funciones básicas de archivos (grabar, leer, abrir, cerrar) pero de forma más genérica: "AbrirArchivo(parametros), en lugar de fopen = (parametros)".

El proyecto necesita grabar 2 archivos, cada uno de una estructura diferente.
Lo que necesito es saber como hacer esta libreria arch.h genérica para aceptar cualquiera de las dos estructuras que le mande por parámetro.
(No puedo usar un #define TIPODATOARCHIVO ty_miregistro porque tengo 2 registros...)
Tampoco estoy familiarizado con el uso de punteros ni objetos.

ARCH.h
Código: Text
  1.  
  2. #ifndef __ARCH_H
  3. #define __ARCH_H
  4. //Librerias
  5. #include <stdio.h>
  6. #include "TDARCH.h"
  7.  
  8. //Prototipos
  9. void AbrirArchivo (FILE * &Arch, bool &bPudo, char * dir, char tipo); //Procedimiento de apertura de archivos de Entrada y de Salida
  10. void LeerArchivo (FILE * &Arch, ty_TDArch &Reg, bool &bFin);  //Procedimiento de lectura de archivo
  11. void GrabarArchivo (FILE * &Arch, ty_TDArch &Reg);  //Procedimiento de guardado de archivo
  12. void CerrarArchivo (FILE * &Arch);  //Procedimiento de cerrado de archivo
  13.  
  14.  
  15. #endif /*__ARCH_H*/
  16.  
  17.  

ARCH.cpp
Código: Text
  1.  
  2. //Librerias
  3. #include "ARCH.h"
  4. #include <iostream.h>
  5.  
  6. ////////////////////////////////////////////////////////////////////////////////////////////
  7. //Rutina LeerArchivo (FILE * &Arch, ESTRUCT &estructura, bool &bfin)
  8. ////////////////////////////////////////////////////////////////////////////////////////////
  9. void LeerArchivo (FILE * &Arch, ty_TDArch &Reg, bool &bFin)
  10.                                                         //Rutina para leer un Archivo
  11.  
  12. {
  13.  
  14.     if (!(feof(Arch))) {                                //Si no es fin de archivo
  15.        fread (&Reg, sizeof(ty_TDArch),1,Arch);     //Leo el archivo
  16.          bFin = FALSE;                                  //No termino la lectura, porque lo lei
  17.     } else {                                            //Caso contrario, Termino la lectura
  18.          bFin = TRUE;
  19.     }
  20. }
  21. //Fin de Rutina -  LeerArchivo (FILE * &Arch, ESTRUCT &estructura, bool &bfin) -
  22.  
  23.  
  24.  
  25. ////////////////////////////////////////////////////////////////////////////////////////////
  26. //Rutina - AbrirArchivo (FILE*Arch,bool&bPudo,char*dir,char tipo) -
  27. ////////////////////////////////////////////////////////////////////////////////////////////
  28. void AbrirArchivo (FILE * , bool &bPudo, char * dir, char tipo)
  29.                                         //Rutina para abrir un archivo de Entrada o de Salida
  30. {
  31.     if (tipo == 'E')  {                 //Si el tipo de archivo es de Entrada
  32.  
  33.         Arch=fopen (dir,"rt");          //Abro el archivo de entrada
  34.  
  35.             if (Arch == NULL) {         //Si no encuentra el archivo
  36.                 cout << "No se pudo abrir el archivo de Entradan";
  37.                 bPudo=FALSE;            //bPudo Abrirlo es FALSO
  38.             }else{
  39.                 bPudo=TRUE;             //Caso contrario bPudo Abrirlo es VERDADERO
  40.             }
  41.  
  42.     } else {                            //Caso contrario el archivo es de Salida
  43.  
  44.         Arch=fopen (dir,"a+");          //Abro el archivo de salida
  45.  
  46.  
  47.             if (Arch == NULL) {         //Si no encuentra el archivo
  48.                 cout << "No se pudo abrir el archivo de Salidan";
  49.                 bPudo=FALSE;            //bPudo Abrirlo es FALSO
  50.             }else{
  51.                 bPudo=TRUE;             //Caso contrario bPudo Abrirlo es                  //VERDADERO
  52.  
  53.             }
  54.  
  55.     }
  56. }
  57. //Fin de Rutina - AbrirArchivo (FILE*Arch,bool&bPudo,char*dir,char tipo) -
  58.  
  59.  
  60. ////////////////////////////////////////////////////////////////////////////////////////////
  61. //Rutina - GrabarArchivo1 (FILE*Arch,ESTRUCT &estructura) -
  62. ////////////////////////////////////////////////////////////////////////////////////////////
  63. void GrabarArchivo1 (FILE * &Arch, ty_TDArch &Reg)
  64. {                                                       //Rutina para grabar un archivo
  65.     fwrite (&Reg, sizeof(ty_TDArch),1,Arch);       //Graba el archivo
  66. }
  67. //Fin de Rutina - GrabarArchivo (FILE*Arch,ESTRUCT &estructura) -
  68.  
  69.  
  70. ////////////////////////////////////////////////////////////////////////////////////////////
  71. //Rutina - CerrarArchivo (FILE * &Arch)
  72. ////////////////////////////////////////////////////////////////////////////////////////////
  73. void CerrarArchivo (FILE * &Arch)
  74. {                                                       //Rutina para cerrar un archivo
  75.     fclose(Arch);                                       //Cierra el archivo
  76. }
  77. //Fin de Rutina - CerrarArchivo (FILE * &Arch)
  78.  
  79.  
  80.  


La idea de esta libreria propia, es que esté encapsulada. Para acceder a los datos de ella, pense hacer un TDARCH.h que la maneje, de esta forma no tendria que romper el encapsulamiento cada vez que quiera cambiar algo.

TDARCH.h

Código: Text
  1. #include "STRCTP3.h"
  2.  
  3. #define FALSE 0
  4. #define TRUE (1 == 1)
  5.  
  6. typedef int bool;
  7.  
  8.  

Ahora bien, tengo 2 registros que contienen lo siguiente:
STRCTP3.H
Código: Text
  1. typedef struct ty_RegOrig{
  2.     ty_VecV VecV;
  3.     ty_VecVB VecVB;
  4. }; //estructura para registro de archivo vectores originales
  5.  
  6. typedef struct ty_RegResult{
  7.     ty_VecResB VecResBOrd;
  8.     ty_VecResB VecResBDes;
  9.     ty_VecResB VecResBBin;
  10.     ty_VecReO VecResOrd;
  11. }; //estructura para registro de archivo vectores de resultados
  12.  
  13.  

Estos 2 registros tengo que guardarlos en 2 archivos diferentes utilizando el mismo procedimiento de guardar. Y ahí está el problema, los tipos de dato son diferentes.

Si alguien me puede explicar como hacer para pasarle directamente una posicion de memoria para que lea "X" tamaño, indiferentemente del tipo, le agradezco mucho.

Espero que se entienda, me cuesta 1 poco explicar esto por acá.

Muchas gracias de antemano.

Saludos.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #1 en: Viernes 8 de Mayo de 2009, 21:31 »
0
¿¿Queres leer/escribir buffers??

Pasa a la funcion que graba un char * (haces casting para pasarle lo que sea) y el tamaño total (de la estructura que queres grabar). Es lo que hacen fread/fwrite al fin y al cabo  B)

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Luciano9

  • Miembro activo
  • **
  • Mensajes: 25
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #2 en: Viernes 8 de Mayo de 2009, 21:40 »
0
Te agradezco la respuesta, pero soy bastante novato en el tema...

Lo que entendí hasta ahora es esto:
Yo tendría que pasarle a mi rutina "genérica" de grabar, un puntero a la posicion de memoria donde empiece mi registro... supongo que será un void * reg... algo asi.
Despues tengo que pasarle el sizeof(miregistro), la cantidad de veces q graba y el archivo con la estructura FILE.

en stdio.h está el encabezado del fwrite como

Código: Text
  1. unsigned fwrite(const void *__ptr, size_t __size_t, size_t __size_n, FILE * __stream);
  2.  

Esto es totalmente generico, porque siendo REG o REGASDAD o REGISTROASD o lo que le pase, va a funcionar.
Lo que quiero saber es como implementarlo en mi rutina (que en definitiva es la misma pero con mis propios nombres)

gracias.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #3 en: Viernes 8 de Mayo de 2009, 21:50 »
0
Código: Text
  1.  
  2. void GrabarArchivo1 (FILE *Arch, void *buffer, unsigned int bufferLen)
  3. {
  4.    fwrite (buffer , 1, bufferLen , Arch);
  5. }
  6.  

Entonces si queres grabar esta estructura ty_RegResult por ejemplo haces asi:

Código: Text
  1.  
  2. FILE *Arch; //no ponemos aca como abrimos el archivo, no interesa
  3. ty_RegResult var; //lo mismo para como inicializamos la estructura
  4. GrabarArchivo1(Arch, (void*)var, sizeof(ty_RegResult));
  5.  

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Luciano9

  • Miembro activo
  • **
  • Mensajes: 25
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #4 en: Viernes 8 de Mayo de 2009, 22:17 »
0
gracias, era eso lo q necesitaba...

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #5 en: Viernes 8 de Mayo de 2009, 22:26 »
0
De nadas  B)

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

fachamix

  • Miembro MUY activo
  • ***
  • Mensajes: 173
  • Nacionalidad: ar
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #6 en: Viernes 8 de Mayo de 2009, 22:44 »
0
muy buen aporte, genial.
La muerte vive celosa, de mi amada flor la vida. Dicen que me anda buscando, ojala si un dia me pilla. Me alle MACHAO Y CANTANDO PA QUE SE MUERA DE ENVIDIA

Luciano9

  • Miembro activo
  • **
  • Mensajes: 25
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #7 en: Sábado 9 de Mayo de 2009, 00:30 »
0
El grabar me anduvo PERFECTO.. hice un programa de prueba pero tengo inconvenientes al leer...

PRUEBA.CPP
Código: C++
  1. #define FLASE 0
  2. #define TRUE (1==1)
  3.  
  4. typedef struct ty_strct {
  5.    int num;
  6.    char letra;
  7.  
  8. typedef int bool;
  9. };
  10.  
  11. void main ()
  12. ty_strct strct, strct2;
  13. FILE *Arch;
  14. FILE *Arch2;
  15. bool bFin, bPudo;
  16. clrscr();
  17. strct.num = 97;
  18. strct.letra = 'A';
  19. AbrirArchivo (Arch,bPudo,"C:\PRUEBA.DAT",'S');
  20. cout << strct.num << endl;
  21. cout << strct.letra << endl;
  22. cout << "Pulse una tecla para grabar...";
  23. getch();
  24. for (int i=0;i<2;i++) {
  25.    GrabarArchivo (Arch,(void*)&strct, sizeof(ty_strct));
  26.    cout << "grabado ok";
  27. }
  28. CerrarArchivo(Arch);
  29. AbrirArchivo(Arch2,bPudo,"C:\PRUEBA.DAT",'E');
  30. cout << "Pulse una tecla para leer el archivo" << endl;
  31. getch();
  32. do {
  33. LeerArchivo (Arch2, (void*)&strct2,sizeof(ty_strct),bFin);
  34. cout << "Archivo cargado "<< endl;
  35. }while (bFin == FALSE);
  36. CerrarArchivo(Arch2);
  37. cout << "Fin de carga" <<endl;
  38. getch();
  39. }
  40.  

RUTINA DE GRABAR:
Código: C++
  1.  
  2. void GrabarArchivo (FILE *Arch, void *Reg, unsigned int tam) {"
  3.   fwrite (Reg,tam,1,Arch);
  4. }
  5.  
  6.  

RUTINA DE LEER:

Código: C++
  1. void LeerArchivo (FILE *Arch, void *Reg, unsigned int tam, bool &bFin) {
  2. if (!(feof(Arch))) {
  3.    fread (Reg,tam,1,Arch);
  4.    bFin == FALSE;
  5.    }else {
  6.    bFin == TRUE;
  7. }
  8. }
  9.  
  10.  


------------------------

El problema es este:

1) ABRO EL ARCHIVO DE SALIDA.
2) GRABO A97 DOS VECES EN EL ARCHIVO
3) CIERRO EL ARCHIVO
4) ABRO EL ARCHIVO DE ENTRADA
5) LEO EL ARCHIVO HASTA Q SEA EL FIN DEL MISMO
**** LEE 4 REGISTROS Y YO GUARDE 2*****

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #8 en: Sábado 9 de Mayo de 2009, 12:17 »
0
Depuralo; sino deja una version compilable.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Luciano9

  • Miembro activo
  • **
  • Mensajes: 25
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #9 en: Domingo 10 de Mayo de 2009, 00:47 »
0
Ya lo solucione... era un temita del while !bFin.

Yo grabo 1 archivo. Quiero que el archivo al leerlo, lea Todos los registros que le grabe. Luego voy a grabar otro registro abajo del registro grabado en el archivo.
Voy a abrir el programa y leer el archivo devuelta, y necesito Que me leea TODOS los registros y no sólo uno.

¿En qué modo tengo que grabar?..


gracias por todas las respuestas.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #10 en: Domingo 10 de Mayo de 2009, 10:03 »
0
Abrilo en modo binario, mira fopen.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Luciano9

  • Miembro activo
  • **
  • Mensajes: 25
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #11 en: Domingo 10 de Mayo de 2009, 16:38 »
0
Abro el archivo de salida en modo a+b (el ejercicio lo pidio en append)
Leo el archivo
while(!FIn){
leo el archivo
Muestro el registro leido
getch();
}
Cierro archivo...

Lo curioso es que me lee el último registro..
La verdad ya no se que probar, voy a tener q entregarlo asi XD

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #12 en: Domingo 10 de Mayo de 2009, 17:25 »
0
a+b deberia estar bien: "Open a file for reading and appending. All writing operations are performed at the end of the file, protecting the previous content to be overwritten. You can reposition (fseek, rewind) the internal pointer to anywhere in the file for reading, but writing operations will move it back to the end of file. The file is created if it does not exist."

Cualquier cosa usa fseek para ponerte al principio ...

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Luciano9

  • Miembro activo
  • **
  • Mensajes: 25
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #13 en: Domingo 10 de Mayo de 2009, 19:14 »
0
Gracias por la ayuda..
Te soy sincero, estuve toda la mañana tratando de implementar esto pero no me sale.

En pocas palabras lo que pense es esto:

Antes de leer el archivo, voy a tener que posicionarme en el inicio del archivo. Así cuando lea, voy a poder leer desde el inicio hasta que termine el archivo.
Ahora bien, hay una funcion que me dijiste que se llama fseek la cual, supuestamente, me permite retroceder pasandole el Arch, el offset y el whence (SEEK_...)
Pero también lei que hay otras como ftell y rewind...
No se cómo aplicar este código a mi razonamiento.

Si me podes dar una mano a nivel codigo, te agradezco.
...

1) AbroArchivodeEntrada(RESULT.....)
2) Vuelvoelpunteroalinicio(....)
3)Leo el archivo
4)Mientras !Fin
5)LEo el archivo

gracias ...

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Parametros genericos....
« Respuesta #14 en: Domingo 10 de Mayo de 2009, 19:37 »
0
ftell es para obtener la posicion en la que se encuentra el stream. rewind, que jamas use, lleva el stream al comienzo del archivo asi que es justamente lo que queres.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.