Day 3 of 5
⏱ ~60 minutes
C Programming in 5 Days — Day 3

Structs, Files & the Standard Library

C structs group related data into custom types. The standard library provides essential utilities for file I/O, string manipulation, math, and sorting. Today you build a complete data management program.

Structs and Typedef

Structs aggregate fields: 'struct Point { double x; double y; };'. Access fields with dot notation (p.x) or arrow for pointers (ptr->x). typedef creates type aliases: 'typedef struct Point Point;' allows 'Point p' instead of 'struct Point p'. Structs can contain other structs, arrays, and function pointers. Struct padding aligns fields for CPU access — use __attribute__((packed)) to disable, but it reduces performance.

File I/O

fopen(path, mode) opens a file; fclose(fp) closes it. Always check for NULL from fopen. fgets(buf, n, fp) reads a line safely. fread/fwrite do binary I/O. fprintf/fscanf do formatted I/O to files. For large files, use fread in chunks rather than line-by-line. Error handling: check return values from every I/O call; use ferror(fp) and feof(fp) to distinguish errors from end-of-file.

Standard Library Essentials

string.h: strlen, strcpy, strncpy, strcat, strcmp, strncmp, memcpy, memmove, memset. math.h: sqrt, pow, floor, ceil, fabs — link with -lm. stdlib.h: atoi, strtol, strtod, qsort, bsearch, rand, srand, abs. qsort(base, n, size, compare_fn) sorts any array given a comparator function. bsearch finds elements in a sorted array. These are the 20 functions you'll use in 80% of C programs.

c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char  name[64];
    float score;
} Student;

int cmp_score(const void *a, const void *b) {
    float sa = ((Student*)a)->score;
    float sb = ((Student*)b)->score;
    return (sa < sb) ? 1 : (sa > sb) ? -1 : 0;  // descending
}

int main(void) {
    FILE *fp = fopen("students.csv", "r");
    if (!fp) { perror("fopen"); return 1; }

    Student roster[100];
    int count = 0;
    char line[128];

    while (fgets(line, sizeof(line), fp) && count < 100) {
        if (sscanf(line, "%63[^,],%f",
                   roster[count].name,
                   &roster[count].score) == 2)
            count++;
    }
    fclose(fp);

    qsort(roster, count, sizeof(Student), cmp_score);

    printf("Top 5 students:\n");
    for (int i = 0; i < 5 && i < count; i++)
        printf("  %d. %s: %.1f\n", i+1, roster[i].name, roster[i].score);
    return 0;
}
💡
Always use strncpy/snprintf/strncat instead of their unbounded counterparts. 'strcpy(dest, src)' with a src longer than dest is a buffer overflow. -Wall will warn about unbounded string functions.
📝 Day 3 Exercise
Build a Student Database
  1. Create a CSV file with 20 students: name and test score
  2. Write the program above to read, sort, and display the top 5
  3. Add a function to write the sorted results to a new CSV file
  4. Add a search function using bsearch (sort by name first for binary search to work)
  5. Compile with -Wall -Wextra -Wno-deprecated and fix all warnings

Day 3 Summary

  • Structs group fields; typedef creates clean type aliases
  • fopen/fclose/fgets/fread/fwrite/fprintf handle all file I/O
  • Always check fopen return for NULL and handle errors with perror()
  • qsort sorts any array with a custom comparator function pointer
  • Use strncpy/snprintf/strncat instead of unbounded string functions
Challenge

Write a C program that reads a text file and produces a word frequency table, sorted by frequency descending. Handle files up to 100MB. Output the top 20 most frequent words with their counts.

Finished this lesson?