Acceder a datos del archivo A utilizando un elemento compartido con un archivo B (claves externas)

Tengo un archivo coche.txt y un archivo reserva.txt. Ambos archivos tienen un número de reserva (Rxxx).

Quiero usar el número de reserva de booking.txt para imprimir los detalles del auto con el número de reserva correspondiente. O más exactamente, estoy tratando de encontrar los detalles de todos los autos que están disponibles en una fecha determinada.

car.txt: (de izquierda a derecha: ID de reserva, ID de coche, YOM de coche, Marca de coche, Modelo de coche, Combustible de coche, categoría)

R002;V001;2003;Toyota;Camry;Petrol;Budget
R007;V002;2005;Toyota;Prius;Petrol;Economy
R001;V003;1999;Ford;Falcon;Petrol;Midsize
R008;V004;2007;Ford;Territory;Diesel;Fullsize
R011;V005;2010;Ferrari;599;Petrol;Fullsize
R035;V006;1998;Holden;Comadore;Diesel;Midsize
R006;V007;2008;Honda;Civic;Petrol;Budget
R004;V008;2000;Mazda;MX5;Petrol;Economy

reserva.txt: (de izquierda a derecha: ID de reserva, ID de cliente, fecha de inicio de reserva, hora de inicio de reserva, fecha de finalización de reserva, hora de finalización de reserva)

R001;C005;12/02/2012;09:15A.M;15/03/2012;05:00P.M
R002;C002;15/04/2012;10:00A.M;22/04/2012;10:30A.M
R003;C003;16/01/2012;02:11P.M;15/04/2012;12:00P.M
R004;C004;05/05/2012;03:00P.M;08/05/2012;10:40A.M
R005;C005;15/04/2012;10:00A.M;23/04/2012;05:00P.M
R006;C006;11/04/2012;05:30P.M;15/04/2012;10:00A.M
R010;C008;15/05/2012;03:15P.M;18/05/2012;11:00A.M
R011;C007;15/04/2012;11:40P.A;23/04/2012;09:00A.M

Si ingreso cualquier fecha, solo llega hasta el punto en que decide si la fecha ingresada está entre la fecha de inicio y finalización de la reserva. "todos los coches están disponibles".

Sin embargo, si introduzco 13/02/2012, imprime "no hay ID de identificación coincidente en cars.txt" 7 veces.

El código en cuestión:

#include <stdio.h>
#include <string.h>
#define MAX_CAR 100
#define MAX_RES 100

int main(){

    typedef struct{                 //car struct
        char reservationID[20];
        char carID[20];
        char carYOM[20];
        char carMake[20];
        char carModel[50];
        char carFuel[20];
        char catagory[20];
    } car_t;

    typedef struct{                 //res struct
        char reservationID[20];
        char customerID[20];
        char reservationStartDate[20];
        char reservationStartTime[20];
        char reservationEndDate[50];
        char reservationEndTime[20];
    } res_t;

    car_t car[MAX_CAR];             //car array
    res_t reservation[MAX_RES];     //res array
    FILE *carHandle;
    FILE *resHandle;
    char line[100];
    char *item;
    int rescount = 0;
    int carcount =0;
    int k;
    int i;
    int option;
    char choice[20];    

    resHandle = fopen("reservation.txt","r");    

    while (fgets(line, 99, resHandle)){                         //cut up the reservation file line by line and put the bits into the res array.
        item = strtok(line,";");
        strcpy(reservation[rescount].reservationID,item);
        item = strtok(NULL,";");
        strcpy(reservation[rescount].customerID,item);
        item = strtok(NULL,";");
        strcpy(reservation[rescount].reservationStartDate,item);
        item = strtok(NULL,";");
        strcpy(reservation[rescount].reservationStartTime,item);
        item = strtok(NULL,";");
        strcpy(reservation[rescount].reservationEndDate,item);
        item = strtok(NULL,"\n");
        strcpy(reservation[rescount].reservationEndTime,item);
        rescount++;
    }

    fclose(resHandle);

    carHandle = fopen("car.txt","r");    

    while (fgets(line, 99, carHandle)){                                 //cut up the car file line by line and put the bits into the car array.
        item = strtok(line,";");
        strcpy(car[carcount].reservationID,item);
        item = strtok(NULL,";");
        strcpy(car[carcount].carID,item);
        item = strtok(NULL,";");
        strcpy(car[carcount].carYOM,item);
        item = strtok(NULL,";");
        strcpy(car[carcount].carMake,item);
        item = strtok(NULL,";");
        strcpy(car[carcount].carModel,item);
        item = strtok(NULL,";");
        strcpy(car[carcount].carFuel,item);
        item = strtok(NULL,"\n");
        strcpy(car[carcount].catagory,item);
        carcount++;
    }

    fclose(carHandle);

    printf("Enter todays date:");
    scanf("%s", choice);
    for (k=0;k<=rescount; k++){
        if (strcmp(choice,reservation[k].reservationEndDate)<0 && strcmp(choice,reservation[k].reservationStartDate)>0){
            for (i=0;i<=carcount; i++){
                if (strcmp(car[k].reservationID,reservation[i].reservationID)==0){
                    printf("\nreservationID: %s\nreservationStartTime: %s\ncustomerID: %s\ncarid: %s\nyom: %s\nmake: %s\nmodel: %s\nfueltype: %s\ncategory: %s\n\n", car[k].reservationID, reservation[i].reservationStartTime, reservation[i].customerID, car[k].carID, car[k].carYOM, car[k].carMake, car[k].carModel, car[k].carFuel, car[k].catagory);
                    //printf("This works");
                    goto outofloop;
                }else printf("\n\nno matching resID in cars.txt\n");
            }
        }
        else printf("\nall the cars are available\n");
        break;
    }
    outofloop:

    return(0);
}

Cualquier ayuda sería apreciada. :)

EDITAR: Código actualizado.

Esta es la salida, sigue siendo incorrecta :(:

Introduzca la fecha de hoy: 13/02/2012

no hay ID de residencia coincidente en cars.txt

reservationID: R002
reservationStartTime: 10:00A.M
customerID: C002
carid: V001
yom: 2003
make: Toyota
model: Camry
fueltype: Petrol
category: Budget

Press any key to continue . . .

Introduzca la fecha de hoy: 13/02/2012

todos los autos estan disponibles

Pulse cualquier tecla para continuar...

preguntado el 03 de mayo de 12 a las 14:05

Tu usas solo uno contador para ambas matrices, que son car y reservation. -

¿Estás seguro de que c es la elección correcta aquí? su tarea suena como un ejemplo perfecto de para qué se creó SQL. -

El código debe estar en c para mis propósitos. -

2 Respuestas

No está contando la cantidad de autos y reservas correctamente: en ambos bucles (el que lee autos y el que lee reservas), está usando reccount como el contador. Necesitas usar dos contadores, carcount y rescount. Más adelante, necesitará usar carcount y recount en sus bucles for.

for (k=0;k<=rescount; k++){
    if (strcmp(choice,reservation[k].reservationEndDate)<0 && strcmp(choice,reservation[k].reservationStartDate)>0){
        for (i=0;i<=carcount; i++){

También debe considerar la asignación dinámica de memoria para las matrices de automóviles y reservas, así como para las matrices de caracteres dentro de car_t y reservation_t, ya que su código actual (incluso cuando se solucione el error obvio) fallará o dará resultados inesperados tan pronto como su entrada los archivos tienen más de MAX_CAR/MAX_RES líneas, o las cadenas en las líneas son demasiado largas.

Noticias Todavía hay varios problemas con su código actualizado:

  • No debe almacenar datos que no se supone que sean una cadena en una variable de cadena. Almacene tanto como sea posible en variables enteras o sin signo, especialmente ID y fechas.
  • Hablando de fechas: simplemente use time(NULL) para obtener la hora actual en formato de hora UNIX ("segundos desde 1970-01-01 00:00"). Almacene todas las fechas como un número entero en tiempo UNIX.
  • Al leer el archivo, verifique si carcount es mayor que CAR_MAX

    for(carcount = 0; carcount < CAR_MAX; carcount++)
    
  • Debe usar fscanf al leer el archivo de texto:

    if(fscanf(filehandle, "R%03u...\n", &car[carcount].reservationID, ...) == EOF)
        break;
    

    Esto hará que su escaneo de archivos sea mucho más robusto y lo convertirá en una sola línea.

  • Evite las comparaciones de cadenas siempre que sea posible. En su lugar, utilice 'tipos de datos reales'.

  • Evita los gotos, de verdad. Es cierto que los desarrolladores del kernel de Linux los usan, pero saben lo que están haciendo.
  • Su bucle for externo contiene una declaración de interrupción que, en todos los casos, interrumpirá la ejecución del bucle después de la primera ejecución. Probablemente olvidaste las llaves después de 'else'.
  • Creo que la lógica de flujo de su programa contiene algunos errores. Ustedes printf("\n\nno matching resID in cars.txt\n") después de cada coche.

En general, ¿ha intentado depurar su código? gdb es una utilidad realmente poderosa. Puede usarlo para seguir el flujo del programa, pausar su programa para ver los contenidos variables en cualquier momento.

contestado el 05 de mayo de 12 a las 16:05

He solucionado el problema. El problema era usar resID como identificador común en lugar de carID.

Gracias a todos por la ayuda.

contestado el 07 de mayo de 12 a las 13:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.