muchas gracias _Lucifer_, tienes razón. He corregido un poco el código, pero me sigue pasando lo mismo...el archivo gastos.dts contiene los siguientes registros en binario:
Código:
| 0 | Nombre 1 | Concepto 1 | 29/ 3/1989 | 0 |
| 1 | Nombre 2 | Concepto 2 | 30/ 3/1989 | 0 |
| 2 | Nombre 3 | Concepto 3 | 31/ 3/1989 | 0 |
| 3 | Nombre 4 | Concepto 4 | 1/ 4/1989 | 0 |
Con esto, la funcion abrir (
en rojo las modificaciones) debería mostrarme siempre los 4 resgistros que hay en gastos.dts:
Código:
void abrir() {
FILE * fp;
fp = fopen("gastos.dts", "rb");
_gasto *aux, *auxSIG;
aux = (_gasto *) malloc(sizeof(_gasto));
auxSIG = (_gasto *) malloc(sizeof(_gasto));
aux->sigGasto = auxSIG;
while (!feof(fp)) {
fread(aux, sizeof(_gasto), 1, fp);
printf(" | %3d | %10s | %30s | %2i/%2i/%4i | %5i |\n",
aux->i, aux->nombre, aux->concepto, aux->fecha.dia,
aux->fecha.mes, aux->fecha.ano, aux->importe);
aux = aux->sigGasto;
}
fclose(fp);
free(aux);
free(auxSIG);
}
Y sin embargo, hay veces que si que me muestra los 4 resgistros, y otras que solo me muestra el primero, de una forma totalmente aleatoria. He probado ya todo lo que se me ocurre, y no consigo arreglarlo :(
La otra duda que me queda es que cuando declaro los punteros a la lista, me toca declarar un puntero para cada elemento que vaya a introducir, y reservarle memoria (
en rojo lo que he añadido):
Código:
int main(char argv[], int argc) {
DB = (_gasto *) malloc(sizeof(_gasto));
DB->sigGasto = (_gasto *) malloc(sizeof(_gasto));
DB->sigGasto->sigGasto = (_gasto *) malloc(sizeof(_gasto));
DB->sigGasto->sigGasto->sigGasto = (_gasto *) malloc(sizeof(_gasto));
abrir();
free(DB);
free(DB->sigGasto);
free(DB->sigGasto->sigGasto);
free(DB->sigGasto->sigGasto->sigGasto);
return 0;
}
Y estoy seguro que se tiene que poder hacer de otra forma, sin tener que declarar 4 punteros y reservarle memoria a los 4...
Mi idea, por si no se entiende bien lo que estoy intentando hacer, es abrir un archivo con un número de registros que yo desconozco, e ir metiendolos en una lista enlazada. Y una vez esten en la lista enlazada, mostrarlos. No los muestro directamente porque después me tocará operar con ellos, por eso los necesito guardar de alguna forma en la memoria, y en la universidad me han dicho que debo hacerlo con listas enlazadas.
Aquí dejo otra vez el código entero con las modificaciones (
en rojo) que le he hecho:
Código:
#include <stdio.h>
#define MAX_N 10 /* MAX_NOMBRE */
#define MAX_C 30 /* MAX_CONCEPTO */
typedef struct {
int dia;
int mes;
int ano;
} _fecha;
struct gasto{
int i;
char nombre[MAX_N];
char concepto[MAX_C];
_fecha fecha;
float importe;
struct gasto * sigGasto;
};
typedef struct gasto _gasto;
_gasto *DB;
void abrir();
void guardar(_gasto *);
int main(char argv[], int argc) {
DB = (_gasto *) malloc(sizeof(_gasto));
DB->sigGasto = (_gasto *) malloc(sizeof(_gasto));
DB->sigGasto->sigGasto = (_gasto *) malloc(sizeof(_gasto));
DB->sigGasto->sigGasto->sigGasto = (_gasto *) malloc(sizeof(_gasto));
abrir();
free(DB);
free(DB->sigGasto);
free(DB->sigGasto->sigGasto);
free(DB->sigGasto->sigGasto->sigGasto);
return 0;
}
// Cada ejecucion da un resultado.
void abrir() {
FILE * fp;
fp = fopen("gastos.dts", "rb");
_gasto *aux, *auxSIG;
aux = (_gasto *) malloc(sizeof(_gasto));
auxSIG = (_gasto *) malloc(sizeof(_gasto));
aux->sigGasto = auxSIG;
while (!feof(fp)) {
fread(aux, sizeof(_gasto), 1, fp);
printf(" | %3d | %10s | %30s | %2i/%2i/%4i | %5i |\n",
aux->i, aux->nombre, aux->concepto, aux->fecha.dia,
aux->fecha.mes, aux->fecha.ano, aux->importe);
aux = aux->sigGasto;
}
fclose(fp);
free(aux);
free(auxSIG);
}
void guardar(_gasto *guardar) {
FILE * fp;
int contador = 0;
/* Abro el archivo gastos.dts para escritura */
fp = fopen("gastos.dts", "wb");
/* Mientras que haya algun registro "gasto" lo escribe en el archivo gastos.dts */
while (guardar != NULL) {
fwrite(guardar, sizeof(_gasto), 1, fp);
guardar = guardar->sigGasto;
contador++;
}
/* Cierra el arhivo */
fclose(fp);
/* Libero memoria */
free(guardar);
printf("Datos guardados: %i", contador);
}
Muchas gracias,
saludos.