Step 8 of 8
Challenge: a CSV report
This challenge is a realistic batch job: read a data file, aggregate it, write a report file. It combines files, strings, arrays of structs and parsing.
CSV
A CSV (comma-separated values) file stores a table as text: one row per line, fields separated by commas, often with a header line naming the columns. Spreadsheets and databases export it everywhere.
Parsing a line with sscanf
sscanf is scanf reading from a string instead of input, perfect for parsing a line you already read with fgets. The format %15[^,] is a scan set: it reads up to 15 characters that are not commas, which is how you grab a text field that ends at a comma.
#include <stdio.h>
int main(void) {
const char *rows[] = {"apples,12", "pears,7", "bad row"};
for (int i = 0; i < 3; i++) {
char name[16];
int count;
if (sscanf(rows[i], "%15[^,],%d", name, &count) == 2) {
printf("%s -> %d\n", name, count);
} else {
printf("skipped: %s\n", rows[i]);
}
}
return 0;
}
apples -> 12
pears -> 7
skipped: bad row
Aggregating by key
To total amounts per region, keep an array of {name, total} structs and a count. For each row, search the array for the region with strcmp; if it's there, add to its total; if not, append a new entry. Appending new keys at the end keeps them in the order they first appeared.
Plan it
- Open the input; skip the header with one
fgets. - For each line: parse, find or add the region, add the amount.
- Open
report.txtfor writing, write one line per region, close it. - Reopen it for reading and print each line.
Check every fopen, and close every file.
Your turn:
sales.csv starts with a header line, then region,amount rows (amounts are whole dollars).
- Skip the header, then total the amounts per region (at most 10 regions, names up to 15 characters), keeping regions in the order they first appear.
- Write
report.txtwith oneREGION TOTALline per region. - Then read
report.txtback and print it, so the test can see what you wrote.
Tip: sscanf(line, "%15[^,],%d", region, &amount) reads everything up to the comma as the region, then the number.