How to read and write files

Open and close a file

fopen returns null on failure. Close every successfully opened stream and report errors with useful context.

FILE *file = fopen("notes.txt", "r");
if (file == NULL) {
    perror("notes.txt");
    return 1;
}
/* use file */
if (fclose(file) == EOF) {
    perror("closing notes.txt");
}

Read bounded lines

fgets never writes more than the supplied array size. Loop until it returns null, then distinguish normal end-of-file from an error.

char line[256];
while (fgets(line, sizeof line, file) != NULL) {
    fputs(line, stdout);
}
if (ferror(file)) {
    perror("reading notes.txt");
}

Write and check

Opening with "w" truncates an existing file. Check output and close results because storage failures may be reported late.

if (fprintf(file, "Score: %d\n", score) < 0) {
    perror("writing report");
}

Handle binary data deliberately

Use "rb" and "wb" where the platform distinguishes modes. Check item counts from fread/fwrite; raw structs are not a portable file format.