C/C++ Arena

Step 2 of 8

Reading lines with fgets

Text files are usually processed line by line. The safe way to read a line is fgets:

char line[256];
fgets(line, sizeof line, f);

It reads characters until the end of the line (and keeps the '\n'), or until the buffer is full, or until the end of the file. It never writes more than sizeof line bytes, so a very long line can't overflow the array; it just arrives in pieces. It returns NULL when there's nothing left, which makes it a natural loop condition.

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

int main(void) {
    FILE *f = fopen("words.txt", "w");
    if (!f) return 1;
    fputs("alpha\nbe\ngamma ray\n", f);
    fclose(f);

    f = fopen("words.txt", "r");
    if (!f) return 1;
    char line[64], shortest[64] = "";
    int count = 0;
    while (fgets(line, sizeof line, f) != NULL) {
        line[strcspn(line, "\n")] = '\0';
        count++;
        if (count == 1 || strlen(line) < strlen(shortest)) {
            strcpy(shortest, line);
        }
    }
    fclose(f);
    printf("%d lines, shortest: %s\n", count, shortest);
    return 0;
}
3 lines, shortest: be

Removing the newline

Because fgets keeps the '\n', you usually want to cut it off before using the line. strcspn(line, "\n") returns the position of the first '\n', or the string's length if there isn't one (for example, a last line without a newline), so line[strcspn(line, "\n")] = '\0'; removes it safely in every case.

Keeping a copy

line is overwritten by every fgets call, so to remember a line (like the longest so far), copy it into a separate array with strcpy. Storing a pointer to line would just point at whatever was read last.

Your task

The folder contains maps.txt. Print how many lines it has and the longest line (the first one, if there's a tie).

Challenge 2

The folder contains chat.txt. Print every line with its line number in front, as N: text. The last line may or may not end with a newline, so strip the newline yourself.

Challenge 3

log.txt has one event per line. Count the lines that contain the word kill anywhere, and print the count and the first such line:

kills: 2
first: ropz kill rain

If there are none, print only kills: 0. strstr(line, "kill") finds text inside a line.

Previous: Write a file, read it back Next: When fopen fails