[C con Clase] Una pequeña duda con los ficheros
Steven Davidson
srd4121 en njit.edu
Jue Abr 26 03:57:34 CEST 2012
Hola Marcos,
On 4/25/2012 5:45 PM, Marcos Collado Martín wrote:
> Ok gracias, pero lo que quiero es que esa función la puedan utilizar
> varias estructuras diferentes, no solo (en tu caso) stDatos. Por
> ejemplo, algo que hizo Salvador antes:
> http://paste2.org/p/1995171
>
El problema es que lo que hizo Salvador y lo que quieres hacer tú son
cosas diferentes. La solución de Salvador se basa en leer cantidades de
bytes de un fichero y escribir los bytes en otra parte del mismo fichero.
En tu ejemplo, quieres leer la información y luego usarla como si fuese
una estructura en particular. Sin embargo, esto va en contra de lo que
quieres, porque dices que te interesa que la información leída se use
con cualquier estructura en general.
Sugiero que la función acepte un puntero a función la cual acepte un
puntero genérico para hacer lo que quieras con tal información, sea el
tipo que sea. Por ejemplo,
typedef void (*PF)( void * );
void Intercambia( FILE *fichero, long iz, long de, long
bytesPorRegistro, PF pfunc )
{
void *reg1, *reg2;
reg1 = malloc(bytesPorRegistro);
reg2 = malloc(bytesPorRegistro);
...
pfunc( reg1 );
}
Un ejemplo de una función y estructura sería,
struct stAlgo
{
char szCad[64];
int num;
};
void asignar( void *pDatos )
{
stAlgo *pReg = (stAlgo *)pDatos;
strcpy( pReg->szCad, "hola mundo" );
pReg->num = 10;
}
Y ahora podemos invocar 'Intercambia()' así,
Intercambia( fichero, a, b, sizeof(stAlgo), asignar );
De esta manera, 'Intercambia()' realizará su tarea además de alguna
tarea específica, 'asignar()' en este ejemplo, que tratará la
información como un tipo particular.
En C++, podemos usar plantillas para resolver este mismo problema. Por
ejemplo,
template< typename T >
void Intercambia( FILE *fichero, long iz, long de )
{
T reg;
fseek( fi, iz*sizeof(T), SEEK_SET );
fread( ®, sizeof(T), 1, fi );
...
reg.memfunc();
reg.memdato = 0;
}
La usaríamos así,
Intercambia< stAlgo >( fichero, a, b );
Claro que no todos los tipos T tendrán el mismo nombre de la función
miembro, 'memfunc()', ni tampoco el nombre del dato miembro, 'memdato'.
La solución para este problema es pasar un puntero a miembro para que
pueda acceder a un miembro cualquiera; por ejemplo,
template< typename T >
void Intercambia( FILE *fichero, long iz, long de, void T::*pfunc() )
{
T reg;
fseek( fi, iz*sizeof(T), SEEK_SET );
fread( ®, sizeof(T), 1, fi );
...
reg.*pfunc();
}
Y la usaríamos así,
Intercambia( fichero, a, b, &stAlgo::m_asignar );
Hay otras soluciones parecidas, pero este tema se complicaría un poco
más y el correo-e sería más extenso.
Espero que esto aclare un poco más el tema.
Steven
Más información sobre la lista de distribución Cconclase