0
votes

I'm having a problem printing out information in the correct format. My program is supposed to read in information about flight reservations. The information should be printed out as an itinerary, like so:

    ******************* Flight Reservation Request  **********************
[email protected] Pete Moss (M 1986/01/01)
123 Boggy Lane
New Orleans, LA 70112
   Flight       Seats      
   H100.15005      2      
   H222.15005      2
   H200.15010      2
   H333.15010      2       
******************* Flight Reservation Request  **********************
[email protected] Pop Corn (M 1957/02/02)
456 Kernel
San Antonio, TX 78210
   Flight       Seats      
   H222.15005      1
   HXXX.XXXXX      1
   H333.15010      1    

Here is most of the code that is important. I am only working in processReservations().

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "cs1713p1.h"
FILE *pFileCust;               // stream Input for Customer Reservation data

void processCommandSwitches(int argc, char *argv[], char **ppszCustomerFileName);
void processReservations();


int main(int argc, char *argv[])
{
    char *pszCustomerFileName = NULL;

    // Process the command switches
    processCommandSwitches(argc, argv,  &pszCustomerFileName);

    // open the Customer Reservation stream data file
    if (pszCustomerFileName == NULL)
        exitError(ERR_MISSING_SWITCH, "-c");

    pFileCust = fopen(pszCustomerFileName, "r");
    if (pFileCust == NULL)
        exitError(ERR_CUSTOMER_RES_FILENAME, pszCustomerFileName);

    // process the Reservations
    processReservations();

    fclose(pFileCust);
    printf("\n");    // included so that you can put a breakpoint on this line
    return 0;
}

/****** Where my errors are coming from *****/

void processReservations()
{

Customer customer;                        // student structure for holding student data
FlightRequest flight;
char szInputBuffer[100];  // input buffer for fgets
int iScanfCnt;                          // scanf returns the number of successful inputs


  // read data input lines of text until EOF.  fgets returns NULL at EOF
    while (fgets(szInputBuffer, 100, pFileCust) != NULL)
    {
        // if the line is just a line feed, skip it.
        if (szInputBuffer[0] == '\n')
            continue;

        iScanfCnt = sscanf(szInputBuffer, "%1c %10s %50s %30[^\n] %50[^,] %2s %2s %5s %10s %d\n"
            , &customer.cGender
            , customer.szBirthDt
            , customer.szEmailAddr
            , customer.szFullName
            , customer.szStreetAddress
            , customer.szCity
            , customer.szStateCd
            , customer.szZipCd
            , flight.szFlightId
            , &flight.iRequestSeats);

        // Check for bad input.  scanf returns the number of valid conversions
        if (iScanfCnt < 10)
        {
            printf("invalid input when reading data, only %d valid values. \n"
                , iScanfCnt);
            printf("\tdata is %s\n", szInputBuffer);
            //return ERR_MISSING_SWITCH;
        }

        printf("******************* Flight Reservation Request  **********************\n");
        printf("%s %s", customer.szEmailAddr, customer.szFullName);
        printf("(%c %s)", customer.cGender, customer.szBirthDt);
        printf("%s, %s %s\n", customer.szStreetAddress, customer.szCity, customer.szZipCd);
        printf("   Flights  Seats\n");
        printf("   %s       %d\n", flight.szFlightId, flight.iRequestSeats);
    }
    fclose(pFileCust);
}

And here is what my output looks like for part of the first customer:

invalid input when reading data, only 4 valid values. 
    data is M 1986/01/01 [email protected] Pete Moss

******************* Flight Reservation Request  **********************
[email protected] Pete Moss
(M 1986/01/01), a a
   Flights  Seats
invalid input when reading data, only 4 valid values. 
    data is 123 Boggy Lane,New Orleans,LA,70112

******************* Flight Reservation Request  **********************
Boggy Lane,New Orleans,LA,70112
(1 23), a a
   Flights  Seats

It's long and messy, obviously, but I am pretty new to C and have to figure out what's going wrong. One problem is that the "Flight Reservation Request" line is printing out way too many times. It seems as if the while loop repeats from the beginning each time a data variable is read from the input file, and I don't know how to fix that. I found a similar issue on another website, and one user suggested

use a temporary variable/struct to test which line of the input file I'm on, so I wouldn't be overwriting my final customer struct each time I'm just testing where I am in the file. Another idea would be to structure my code based on assumptions I can make from the input file. For example, if I've successfully read the first line of a new customer, then I know the next lines will follow some other format, so I won't have to check whether each subsequent line is the first line of a new customer.

I don't understand what either of these proposed solutions means or how to fix this code but I've been struggling with it for a long time with no progress. There is also a .h file that is included with all of my variable declarations, however the lowercase letters before each variable name idicate what data type the variable is (sz=string, c=char, i=int). What's the issue?

1
I don't see how you can expect to read a variable number of (flight id, seat count) pairs with a single scanf() call.John Bollinger
The field descriptor corresponding to the city (%2s) looks wrong. Also, your intent seems to be to skip the commas in the address, but you're not doing that. If your format does not match them as literals then either they will be included in one of the fields or they will cause a matching failure.John Bollinger
You are reading a single line of input at a time, but trying to scan several lines worth of data out of that one line.John Bollinger
so should I make a scanf statement for every line?user6461363

1 Answers

1
votes

The program reports the error

invalid input when reading data, only 4 valid values

This is because the input buffer

char szInputBuffer[100];

is too small. The sum of the field width limitations in

iScanfCnt = sscanf(szInputBuffer, "%1c %10s %50s %30[^\n] %50[^,] %2s %2s %5s %10s %d\n", ...);

is way bigger. So it is likely that

while (fgets(szInputBuffer, 100, pFileCust) != NULL)

will break each line input into several smaller strings, which you do not detect (lack of trailing newline). However the sscanf does fail.

Don't be mean. Use a generous buffer such as

char szInputBuffer[4096];