Home

Two Ways to Count Vowels in C: Switch vs. Nested Loops

When learning C, strings present an exciting challenge because they aren’t a built-in high-level data type—they are simply arrays of characters ending with a null terminator (\0). To explore how we can manipulate strings and manage control flow, we can look at two completely different strategies to solve a classic problem: Counting vowels in a string.


Method 1: The Switch Statement Approach

This method uses an optimized switch statement that evaluates each character of the string directly against an explicit list of matches.

#include <stdio.h>

int count_vowels_switch(const char *str);

int main(void) {
    char test1[] = "Wojtek";
    char test2[] = "Tomaszewski";
    char test3[] = "";
    char test4[] = "Alice";

    printf("--- Testing Version 1: Switch Statement ---\n");
    printf("Number of vowels in %s is %d\n", test1, count_vowels_switch(test1));
    printf("Number of vowels in %s is %d\n", test2, count_vowels_switch(test2));
    printf("Number of vowels in %s is %d\n", test3, count_vowels_switch(test3));
    printf("Number of vowels in %s is %d\n", test4, count_vowels_switch(test4));

    return 0;
}

int count_vowels_switch(const char *str) {
    int counter = 0;

    while (*str != '\0') {
        switch (*str) {
            case 'a':
            case 'e':
            case 'i':
            case 'o':
            case 'u':
            case 'y':
            case 'A':
            case 'E':
            case 'I':
            case 'O':
            case 'U':
            case 'Y':
                counter++;
                break;
        }
        str++; /* Advance pointer to the next character */
    }
    return counter;
}

Code Architecture & Design Notes (Switch Version)


Method 2: The Nested Loops Approach

This method takes a dynamic approach by cross-referencing each character of the input text against a standalone string literal containing all targets.

#include <stdio.h>

int count_vowels_nested(const char *str);

int main(void) {
    char test1[] = "Wojtek";
    char test2[] = "Tomaszewski";
    char test3[] = "";
    char test4[] = "Alice";

    printf("--- Testing Version 2: Nested Loops ---\n");
    printf("Number of vowels in %s is %d\n", test1, count_vowels_nested(test1));
    printf("Number of vowels in %s is %d\n", test2, count_vowels_nested(test2));
    printf("Number of vowels in %s is %d\n", test3, count_vowels_nested(test3));
    printf("Number of vowels in %s is %d\n", test4, count_vowels_nested(test4));

    return 0;
}

int count_vowels_nested(const char *str) {
    const char *vowels = "aeiouyAEIOUY";
    int counter = 0;

    while (*str != '\0') {
        /* Inner loop checks the current character against every vowel in our reference string */
        for (int j = 0; vowels[j] != '\0'; j++) {
            if (*str == vowels[j]) {
                counter++;
                break; /* Stop checking other vowels once a match is found */
            }
        }
        str++; /* Advance pointer to the next character */
    }
    return counter;
}

Code Architecture & Design Notes (Nested Loops Version)


Algorithmic Complexity Analysis

Understanding how code behaves as input scales is vital for writing performant systems software. Here is the breakdown for both approaches:

Time Complexity

Space (Memory) Complexity

Tags: CStringAlgorithms