C/C++ Arena

Step 4 of 8

Loading records

Much of the world's data lives in simple text formats: one record per line, with fields separated by spaces or commas. Loading such a file into an array of structs is a very common task.

fscanf reads fields directly into variables, and like scanf it returns how many fields it matched. Comparing that with the number you asked for tells you when to stop: at the end of the file it returns EOF, and on a malformed line it returns fewer.

#include <stdio.h>

typedef struct {
    char item[24];
    int qty;
    double price;
} Line;

int main(void) {
    FILE *f = fopen("order.txt", "w");
    if (!f) return 1;
    fputs("pen 3 1.50\nnotebook 2 4.25\nstapler 1 9.99\n", f);
    fclose(f);

    Line lines[10];
    int n = 0;
    f = fopen("order.txt", "r");
    if (!f) return 1;
    while (n < 10 && fscanf(f, "%23s %d %lf", lines[n].item, &lines[n].qty, &lines[n].price) == 3) {
        n++;
    }
    fclose(f);
    double total = 0;
    for (int i = 0; i < n; i++) {
        total += lines[i].qty * lines[i].price;
    }
    printf("%d lines, total %.2f\n", n, total);
    return 0;
}
3 lines, total 22.99

Details that make it robust

Your turn: roster.txt holds name score pairs. Load them into the array (at most 32) and print the player with the highest score, then the average score with one decimal place.

Previous: When fopen fails Next: Appending