Back to blog
Cottimizzazionealgoritmiprogrammazione

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.

Published May 14, 20263 min read
Algorithmic improvement in C: counting characters with fgetc()

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:

  1. Start
  2. Input: filename from user
  3. Open file in read mode
  4. If file does not exist → error and exit
  5. If exists → loop reading character by character until EOF
  6. For each character:
    • if it's 'a' → increment count_a
    • if it's not newline '\n' → increment count_total
  7. Print both results
  8. 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!