Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Registro Estatico & Registro Dinamico en C

Estas en el tema de Registro Estatico & Registro Dinamico en C en el foro de C/C++ en Foros del Web. Buenos dias: Necesito leer un fichero de texto de vuelos y otro de pasajeros guardarlo en memoria en un array de registros, y posteriormente gestionarlo ...
  #1 (permalink)  
Antiguo 13/08/2013, 03:54
 
Fecha de Ingreso: febrero-2008
Mensajes: 3
Antigüedad: 16 años, 2 meses
Puntos: 0
Registro Estatico & Registro Dinamico en C

Buenos dias:

Necesito leer un fichero de texto de vuelos y otro de pasajeros guardarlo en memoria en un array de registros, y posteriormente gestionarlo de momento he conseguido leer uno y gestionarlo, pero no se como almacenarlo en memoria dinamica para que vaya leyendo todos.
Los problemas principales es que debo leer de un fichero de texto con los campos separados por almohadillas y la otra duda es que debo almacenar todo el texto en memoria sin saber el numero de registros a almacenar.
Adjunto programa que ya he hecho por si me podeis echar una mano.

#include <stdio.h>

typedef struct Reg_Vuelos
{
char IDVuelo[6];
char Operadora[7];
char Aerolinea[5];
char TipoAvion[4];
char NumPasajV[4];
struct Reg_Vuelos *Siguiente;
}Reg_Vuelos;

typedef struct Reg_Pasajeros
{
char NumPasajP[4];
char DNI[9];
char Nombre[30];
char Aerolinea[5];
char TipoAvion[4];
char Fecha;
}Reg_Pasajeros;

Reg_Vuelos RVuelos;
Reg_Pasajeros RPasajeros;


int main ()
{
int Var_Aux = 1; // Variable Auxiliar utilizada para recorrer cada uno de los campos del Registro RegVuelos.

// Variables utilizadas dentro del bucles que verifica cuantos clientes vuelan el mismo dia.
int p;
int Coincidencias = 0;
int Repeticiones = 0;
int k = 0;
int Avance;

char i = 0; // Variable utilizada para rellenar cada uno de los caracteres de los campos del Registro RegVuelos.
char j = 1; // Variable utilizada para rellenar el campo de los vuelos en que no viajan clientes de nuestra operadora.
char Cadena_AuxV[40]; // Cadena Auxiliar para recorrer el Archivo Vuelos.txt.
char Cadena_AuxP[40]; // Cadena Auxiliar para recorrer el Archivo Pasajeros.txt.

// Variables utilizadas para Contabilizar los clientes que vuelan en estas Aerolineas.
int Iberia = 0;
int Luftansa = 0;
int American = 0;
int Ryanair = 0;

printf ("Ejecutando proceso. \n\n");

printf ("Fichero Informe rellenado. Pulse una tecla \n\n");

// Apertura de los tres ficheros de texto a utilizar, Vuelos y Pasajeros en modo lectura y el fichero de salida, Informe en modo escritura

FILE *Vuelo = fopen("Vuelos.txt", "r");
if (Vuelo == NULL)
{
perror ("Error al abrir fichero.txt");
return -1;
}
FILE *Pasajero = fopen("Pasajeros.txt", "r");
if (Pasajero==NULL)
{
perror ("Error al abrir fichero.txt");
return -1;
}
FILE *Informe = fopen("Informe.txt", "w");
if (Informe==NULL)
{
perror ("Error al abrir fichero.txt");
return -1;
}

fprintf (Informe, "Clientes que vuelan mas de dos veces el mismo dia: \n");

// Comienza el bucle principal

do

{

Var_Aux = 1;
i = 0;

// Leemos una linea completa del fichero Vuelos.txt y la vamos guardando en la estructura registro

do
{
Cadena_AuxV[1] = fgetc (Vuelo);
if (Var_Aux == 1)
{
i++;
RVuelos.IDVuelo[i]= Cadena_AuxV[1];
if (Cadena_AuxV[1] == '#')
{
Var_Aux++;
i = 0;
Cadena_AuxV[1] = fgetc (Vuelo);
}
}
if (Var_Aux == 2)
{
i++;
RVuelos.Operadora[i]= Cadena_AuxV[1];
if (Cadena_AuxV[1] == '#')
{
Var_Aux++;
i = 0;
Cadena_AuxV[1] = fgetc (Vuelo);
}
}
if (Var_Aux == 3)
{
i++;
RVuelos.Aerolinea[i]= Cadena_AuxV[1];
if (Cadena_AuxV[1] == '#')
{
Var_Aux++;
i = 0;
Cadena_AuxV[1] = fgetc (Vuelo);
}
}
if (Var_Aux == 4)
{
i++;
RVuelos.TipoAvion[i]= Cadena_AuxV[1];
if (Cadena_AuxV[1] == '#')
{
Var_Aux++;
i = 0;
Cadena_AuxV[1] = fgetc (Vuelo);
}
}
if (Var_Aux == 5)
{
i++;
RVuelos.NumPasajV[i] = Cadena_AuxV[1];
}
}
while (Cadena_AuxV[1] != '\n');

// Comprobamos si el cliente es de Nuestra Operadora que Aerolinea ha preferido.

if (RVuelos.Operadora[1] == 'N')
{
switch (RVuelos.Aerolinea[1])
{
case 'I':
Iberia ++;
break;
case 'A':
American ++;
break;
case 'R':
Ryanair ++;
break;
case 'L':
Luftansa ++;
break;
}
}
else
{
fprintf (Informe, "\nVuelo en el que no viajan clientes de nuestra operadora: ");
for (j=1; j<7; j++)
{

fprintf (Informe, "%c", RVuelos.IDVuelo[j]);
}
fprintf (Informe, "\n");
}

// Este bucle lee el fichero Pasajeros, para comprobar si un cliente vuela varias veces en el mismo dia.

do
{
k = 1;

do
{
Avance = 0;
Cadena_AuxP[1] = fgetc (Pasajero);
RPasajeros.NumPasajP[k]= Cadena_AuxP[1];


if (RPasajeros.NumPasajP[k] == RVuelos.NumPasajV[k])
{

Coincidencias ++;
if (Coincidencias == 4)
{

Repeticiones ++;



Coincidencias = 0;
if (Repeticiones == 2)
{
while (Cadena_AuxP[1] != '#')
{
Cadena_AuxP[1] = fgetc (Pasajero);
}
for (p = 1; p<10; p++)
{
Cadena_AuxP[1] = fgetc (Pasajero);
RPasajeros.DNI[p]= Cadena_AuxP[1];
fprintf (Informe,"%c", RPasajeros.DNI[p]);

}
Cadena_AuxP[1] = fgetc (Pasajero);
fprintf(Informe,"\n");
Repeticiones = 0;

for (p = 1; p<14; p++)
{
Cadena_AuxP[1] = fgetc (Pasajero);
RPasajeros.Nombre[p]= Cadena_AuxP[1];
fprintf (Informe, "%c", RPasajeros.Nombre[p]);
}
fprintf (Informe,"\n");
Avance = 1;
for (p = 1; p<13; p++){
Cadena_AuxP[1] = fgetc (Pasajero); }
}

}

}
else
{
Coincidencias = 0;
}
k ++;

}
while (k < 5);
if (Avance != 1)
{for (p = 1; p<37; p++){
Cadena_AuxP[1] = fgetc (Pasajero);}}
}
while ((Cadena_AuxP[1]=fgetc(Pasajero)) != EOF);





}
while ((Cadena_AuxV[1]=fgetc(Vuelo)) != EOF);


fclose (Vuelo);
fclose (Pasajero);
fclose (Informe);
getch();
system ("PAUSE");
return 0;
}
  #2 (permalink)  
Antiguo 13/08/2013, 13:12
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Registro Estatico & Registro Dinamico en C

Indenta el codigo para que se vea mejor lo que estas haciendo.

Para separar los campos solo tienes que tokenizar por el caracter que quieras; echa un vistazo a tu manual de c para la funcion strtok: ojo, si vas a parsear mas de un texto simultaneamente con multiples procesos busca la funcion strtok_r que es la version reentrante de la strtok estandar (la funcion estandar no es segura en multiprocesos porque guarda datos).

Código C:
Ver original
  1. char texto[] = "campo1#campo2#campo3";
  2. char *pch;
  3.  
  4. pch = strtok(texto, "#");
  5. while(pch) {
  6.     printf("%s\n", pch);
  7.     pch = strtok(0, "#");
  8. }

Ten en cuenta una cosa: la funcion strtok modifica la cadena que le envias, por eso si necesitas reutilizar los datos sería una buena opcion hacer una copia y trabajar con eso.

Para cargar los archivos en memoria solo tienes que conocer su longitud, bloquear memoria para ese tamaño y leer el archivo; recuerda que tienes que liberar la memoria bloqueada cuando ya no la necesites. Para consultar el tamaño de un archivo tienes varias formas (a parte de las funciones que tengas en las api de cada s.o.): buscando el final del archivo o bien usando la funcion stat (ambas deberian darte lo mismo, pero la primera se usa cuando no conoces la ruta del archivo pero tienes un puntero abierto):

Código C:
Ver original
  1. size_t get_file_size(FILE *arx) {
  2.     size_t fs = 0;
  3.  
  4.     if(arx) {
  5.         fseek(arx, 0L, SEEK_END);
  6.         fs = ftell(arx);
  7.         fseek(arx, 0L, SEEK_SET);
  8.     }
  9.  
  10.     return fs;
  11. }

Ya tienes la funcion que te da el tamaño, solo tienes que abrir un puntero al archivo, usarlo con esta funcion, bloquear la memoria requerida y leer:

Código C:
Ver original
  1. FILE *arx;
  2. long unsigned int nb, nbr;
  3. char *buffer;
  4.  
  5. if((arx = fopen("datos.txt", "rb"))) {
  6.     if((nb = get_file_size(arx))) {
  7.         if((buffer = malloc(nb+1))) {
  8.             if((nbr = fread(buffer, nb, 1, arx)) == 1) {
  9.                 buffer[nb] = '\0';
  10.                 //aqui ya tienes todo el archivo en buffer
  11.                 //printf("%s", buffer);
  12.                 free(buffer);
  13.                 buffer = 0;
  14.             }
  15.         }
  16.     }
  17. }

(nota: los else de todos los 'if' son las condiciones de error, no las he puesto pero se la idea basica se entiende)

Una vez tienes el archivo lo tokenizas y vas populando la lista.

Saludos
vosk

p.s. que me olvido una cosa, el tipo size_t es una redefinicion de long unsigned int; te sirve para saber que tipos de datos esperan las funciones

Etiquetas: dinamico, estatico, int, numero, programa, registro, struct
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:57.