IPC144 Lab 11 - Files (Mr. Saul's sections)

Weekly Tip: When you are done writing to a file, remember to close the file. Closing ensures that all data gets to the device on which the file resides, including any data waiting in memory until there is enough data to justify writing to that device.

This is a modified version of the lab on the IPC144 page.

In this lab, you will work with files. If you have problems, ask for help - that is what the lab sessions are for.

NOTE: When you have completed this lab, and placed answers into the file called "lab11.txt", follow the instructions (at the bottom of this lab) to submit your answers to Murray Saul's e-mail account...

Enter the following program and call it lab11a.c

   #include <stdio.h>
main() {
FILE *fp;
char line[81], filename[81];
printf("Enter a file name: ");
gets(filename);
fp = fopen(filename, "a");
if (fp == NULL)
printf("Cannot open %s\n", filename);
else {
do {
printf("Enter a line: ");
gets(line);
if (line[0] != '\0')
fprintf(fp,"%s\n", line);
} while (line[0] != '\0');
fclose(fp);
}
}
  1. This program takes lines of input from the user and places them in a file, until the user just hits <Enter> by itself. Answer the following questions to your satisfaction:


                ___________________________________________________________________________________________________
  2. Now enter the following lines using any text editor and save to a file named lab11.dat :
       102;Hyper VGA board;59.95
    213;40 GB Hard Drive;239.99
    73;P4 motherboard;199.00
    and enter the following program and call it lab11b.c
       #include <stdio.h>
    #include <string.h>
    void locate (FILE *fp, int partnum, char desc[], double *pprice) {
    int pnum,
    varsread,
    found = 0;
    rewind(fp);
    varsread = fscanf(fp, "%d;%30[^;];%lf%*c", &pnum, desc, pprice);
    while (found == 0 && 3 == varsread)
    if (pnum == partnum)
    found = 1;
    else
    varsread = fscanf(fp, "%d;%30[^;];%lf%*c", &pnum, desc,
    pprice);
    if (found == 0) {
    strcpy(desc, "Part Not Found");
    *pprice = 0;
    }
    }
    main() {
    FILE *fp;
    int part;
    char desc[31];
    double price;
    fp = fopen("lab11.dat", "r");
    if (fp == NULL)
    printf("Cannot open lab11.dat\n");
    else {
    do {
    printf("Enter a part number (0 to stop): ");
    scanf("%d", &part);
    if (part != 0) {
    locate(fp, part, desc, &price);
    printf("Description: %s, Price: $%.2lf\n", desc, price);
    }
    } while (part != 0);
    fclose(fp);
    }
    }
    This program looks up part numbers in the lab11.dat file. Try the program out, entering part numbers which are on file (102, 213 and 73), and some which aren't. Be sure that you understand how the program works. For example, can you explain the following?


                ___________________________________________________________________________________________________
    Also, note that since each fscanf call in locate first looks to match %d (which is designed to skip over white space), it really isn't necessary in this case to discard the newline at the end of each line of the file. Remove the %*c to prove this. Did this work? __________________

  3. Copy lab11b.c to lab11c.c. In lab11c.c, add the following functions:
       int load(FILE *fp, int pnums[], char descs[][31], double prices[]) {
    int i = 0;
    while (3 == fscanf(fp, "%d;%30[^;];%lf%*c", &pnums[i], descs[i],
    &prices[i]))
    i++;
    return i;
    }
    void locate2(int pnum, char desc[], double *pprice, int pnums[],
    char descs[][31], double prices[], int count) {
    int i = 0;
    while (i < count && pnum != pnums[i])
    i++;
    if (i == count) {
    strcpy(desc, "Part Not Found");
    *pprice = 0;
    } else {
    strcpy(desc, descs[i]);
    *pprice = prices[i];
    }
    }
    and modify main so that it looks like this:
       main() {
    FILE *fp;
    int part, parts[40], count;
    char desc[31], descs[40][31];
    double price, prices[40];
    fp = fopen("lab11.dat", "r");
    if (fp == NULL)
    printf("Cannot open lab11.dat\n");
    else {
    count = load(fp, parts, descs, prices);
    fclose(fp);
    do {
    printf("Enter a part number (0 to stop): ");
    scanf("%d", &part);
    if (part != 0) {
    locate2(part, desc, &price, parts, descs, prices, count);
    printf("Description: %s, Price: $%.2lf\n", desc, price);
    }
    } while (part != 0);
    }
    }
    Satisfy yourself that this works the same as the program in lab11b.c.

    This version uses the technique of reading the entire file into memory at once, and then doing the parts lookup without having to continually reread the file.

    What could be the advantages of this approach over that used in lab11b.c?

    ________________________________________________________________________________________________________
    What could be the disadvantages?

    ________________________________________________________________________________________________________

  4. [If you have time] One flaw in lab11c.c that if the file has more than 40 records, memory will be corrupted and the program will likely crash. Can you change your program to remove this potential problem? (Hint: stop reading from the file when you reach the end of the file or when the arrays are full, whichever comes first).

Submission Requirements:

If you are in Murray Saul's class, issue the following command to send your lab #5 answers to Murray Saul:

mail -s "144lab11" -c $USER@learn.senecac.on.ca murray.saul@senecac.on.ca < lab11.txt

The option -s "144lab11" makes subject line appear as "144lab11" so instructor can filter these e-mails in a directory to collect all lab11 submissions.

The option -c $USER@learn.senecac.on.ca sends a copy of the e-mail message to YOUR learn account. The variable $USER is your Matrix id name assuming that you are issuing this command when logged into your Matrix account. Please keep this e-mail for the remainder of this term as proof that you sent your lab by the required deadline...