Algorithmic improvement in C: counting characters with fgetc()
How to think about optimizing C code, delegating computations to low-level languages and improving performance. First exercise: count lowercase 'a' and total characters from a file.

In this new series on algorithmic improvement in C (not a pure C tutorial), we will learn how to think better, optimize code, and expand our mental vision. These skills become crucial when, during public building, server resources grow and we face poorly optimized software. We will learn to:
- allocate resources efficiently
- reduce CPU overhead
- delegate computation to a low-level language to optimize routing in a high-level one
👉 Video Link (YouTube Video)
The first exercise
The exercise is:
A text file, whose name is requested from the user, contains arbitrary characters. Write a C89 program that:
- counts how many lowercase letters
'a'are present- counts how many total characters are present
- displays both results. Use
fgetc().
Reasoned flowchart
Before writing code, let's sketch the logic:
- Start
- Input: filename from user
- Open file in read mode
- If file does not exist → error and exit
- If exists → loop reading character by character until EOF
- For each character:
- if it's
'a'→ incrementcount_a - if it's not newline
'\n'→ incrementcount_total
- if it's
- Print both results
- Close file and exit
C89 implementation
Here is the complete code, with necessary precautions to avoid common errors (like segmentation faults due to mishandled pointers):
/* QUESTION 1. (6 points) A text file, whose name is requested from the user, contains arbitrary characters. Write a C89 program that: - counts how many lowercase letters 'a' are present - counts how many total characters are present - displays both results. Use fgetc(). */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 20 int main(){ char nome_file[MAX]; printf("Enter filename: "); scanf("%s", nome_file); FILE *fp; fp = fopen(nome_file, "r"); if(!fp){ return EXIT_FAILURE; } int ch, count_a = 0, count_total = 0; while ( (ch = fgetc(fp)) != EOF ){ if(ch == 'a'){ count_a = count_a + 1; } if (ch != '\n'){ count_total++; } } printf("Total lowercase 'a': %d\n", count_a); printf("Total characters (excluding newlines): %d", count_total); fclose(fp); return EXIT_SUCCESS; }
Why exclude \n?
When counting total characters, the original exercise usually refers to printable or visible characters only, excluding newlines. In the video we noticed a discrepancy with an AI's count: the file had 388 characters (excluding newlines) and the program, after adding ch != '\n', produced the same result. Without that filter, newlines are counted extra, skewing the total.
Implicit optimization lessons
Even a simple exercise teaches important principles:
- Use a single loop to avoid reading the file twice (saves I/O).
- Immediately discard unnecessary characters (like
\n) without storing them. - Handle errors (file not found) with
EXIT_FAILURE. - Follow C89 standard (declarations at block start, no
//comments).
Delegating counting operations to a low-level language like C frees resources in higher-level languages (Python, JavaScript, etc.) when they handle routing or complex logic. This is the core of the series: don't write everything in C, but use C for computational bottlenecks.
Coming next: memory management, pointers, and sorting algorithm optimization. Happy coding!