Sort a String Alphabetically in C – Case-Sensitive and Case-Insensitive

To sort a string alphabetically in C, apply bubble sort to the character array: compare adjacent characters and swap them when the left character is greater than the right. After all passes, the characters are in ascending ASCII order — digits first, then uppercase A–Z, then lowercase a–z. For a sort that treats ‘A’ and ‘a’ as equal, use tolower() from <ctype.h> in the comparison while keeping the original case in the array. This page gives both approaches with full working programs and a character-by-character trace.

How ASCII Ordering Affects the Sort

Understanding why ‘P’ appears before ‘a’ in a case-sensitive sort requires knowing the ASCII values:

Character range ASCII values Sort position
Digits 0–9 48–57 First
Uppercase A–Z 65–90 Second
Lowercase a–z 97–122 Third

A case-sensitive sort on “Programming” produces “Paggimmnorr” — ‘P’ (ASCII 80) sorts before ‘a’ (ASCII 97). A case-insensitive sort treats ‘P’ and ‘p’ as the same value (both map to ‘p’=112 via tolower), so ‘P’ moves to its alphabetical position among the other letters: “aggimmnoPrr”.

Bubble Sort Trace for “banana”

Initial: b a n a n a (ASCII: 98 97 110 97 110 97)

Pass Result after pass Swaps made
1 a a b n a n b↔a, n↔a, n↔a (3 swaps)
2 a a a b n n b↔a, n↔b (2 swaps)
3 a a a b n n 0 swaps (already sorted)
Final a a a b n n

C Program: Sort String Alphabetically

/* Sort a string alphabetically — case-sensitive and case-insensitive
 * Compile: gcc -ansi -Wall -Wextra sortstr.c -o sortstr */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 256

/* Case-sensitive sort: compare raw ASCII values. */
void bubble_sort(char s[], int n)
{
    int i, j;
    char tmp;
    for (i = 0; i < n - 1; i++)
        for (j = 0; j < n - 1 - i; j++)
            if (s[j] > s[j + 1]) {
                tmp = s[j]; s[j] = s[j + 1]; s[j + 1] = tmp;
            }
}

/* Case-insensitive sort: compare lowercased values, keep original case. */
void sort_ignore_case(char s[], int n)
{
    int i, j;
    char tmp;
    for (i = 0; i < n - 1; i++)
        for (j = 0; j < n - 1 - i; j++)
            if (tolower((unsigned char)s[j]) > tolower((unsigned char)s[j + 1])) {
                tmp = s[j]; s[j] = s[j + 1]; s[j + 1] = tmp;
            }
}

int main(void)
{
    char s1[MAX], s2[MAX];
    int len;

    printf("Enter a string: ");
    if (!fgets(s1, sizeof(s1), stdin)) {
        printf("Error reading input.\n"); return 1;
    }
    s1[strcspn(s1, "\n")] = '\0';    /* remove newline from fgets */
    len = (int)strlen(s1);

    strncpy(s2, s1, MAX - 1);        /* copy for second sort */
    s2[MAX - 1] = '\0';

    printf("Original:                  %s\n", s1);

    bubble_sort(s1, len);
    printf("Case-sensitive sort:       %s\n", s1);

    sort_ignore_case(s2, len);
    printf("Case-insensitive sort:     %s\n", s2);

    return 0;
}

Sample Output

Enter a string: banana
Original:                  banana
Case-sensitive sort:       aaabnn
Case-insensitive sort:     aaabnn

Enter a string: Programming
Original:                  Programming
Case-sensitive sort:       Paggimmnorr
Case-insensitive sort:     aggimmnoPrr

Code Explanation

  • fgets(s1, sizeof(s1), stdin): Reads up to MAX−1 characters including the newline. Safer than scanf("%s"), which stops at whitespace, and safer than the dangerous gets(), which has no length limit. The strcspn(s1, "\n") = '\0' line trims the newline that fgets includes.
  • Bubble sort on characters: The comparison s[j] > s[j+1] uses C’s built-in char comparison, which compares ASCII values. Every character is just an integer under the hood. Swapping two chars is identical to swapping two ints — a temporary variable and three assignments.
  • tolower((unsigned char)s[j]): The cast to unsigned char is required by the C standard. tolower() is defined for values in the range of unsigned char and EOF. Plain char is signed on most platforms, so characters with values above 127 (like accented letters in extended ASCII) would be passed as negative integers, causing undefined behaviour. The cast makes it safe.
  • strncpy(s2, s1, MAX-1): We copy the original into s2 before the first sort so the second sort starts from unsorted input. Without this, the second sort would operate on the already-sorted s1.
  • The inner loop bound n - 1 - i: After each pass, the largest i characters are already in their final position at the end of the array. Reducing the inner loop bound by i avoids comparing elements that are already settled — an optimization that roughly halves the total work.

Sorting Words (Strings) vs Sorting Characters

This post sorts the characters within a single string. To sort an array of strings (words) alphabetically, use strcmp() for comparison instead of the > operator:

/* Sort an array of strings alphabetically */
#include <stdio.h>
#include <string.h>
#define MAXWORDS 20
#define MAXLEN 50

void sort_words(char words[][MAXLEN], int n)
{
    int i, j;
    char tmp[MAXLEN];
    for (i = 0; i < n - 1; i++)
        for (j = 0; j < n - 1 - i; j++)
            if (strcmp(words[j], words[j + 1]) > 0) {
                strcpy(tmp, words[j]);
                strcpy(words[j], words[j + 1]);
                strcpy(words[j + 1], tmp);
            }
}

int main(void)
{
    char words[MAXWORDS][MAXLEN] = {"cherry", "apple", "banana", "date"};
    int n = 4, i;
    sort_words(words, n);
    for (i = 0; i < n; i++) printf("%s\n", words[i]);
    return 0;
}

Output: apple, banana, cherry, date.

Frequently Asked Questions

How do you sort a string in reverse alphabetical order in C?

Reverse the comparison: change s[j] > s[j+1] to s[j] < s[j+1]. Larger ASCII values (z, y, x…) will bubble to the front. For “banana” this gives “nnbaaa”. The rest of the bubble sort code stays identical.

How do you sort only the letters in a string, leaving digits and spaces in place?

Extract only alphabetic characters: loop through the string, copy each character where isalpha(s[i]) is true into a buffer, sort the buffer, then scan the original string again and replace each alphabetic position with the next character from the sorted buffer in order.

What does qsort look like for sorting a string in C?

Include <stdlib.h>, define a comparator int cmp(const void *a, const void *b) { return *(const char*)a - *(const char*)b; }, then call qsort(s, strlen(s), sizeof(char), cmp);. This uses the C standard library’s quicksort and is O(n log n) versus bubble sort’s O(n²).

Related Programs

Recommended books:
The C Programming Language — K&R (India) |
(US)
 | 
C Programming: A Modern Approach — K.N. King (India) |
(US)

Test your C knowledge: C Aptitude Questions — or try our C Programming Quiz App on Android.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>