Nearby lessons

68 of 124

C - String Characters

Working with the individual characters of a string — indexing, modifying, and classifying them with the <ctype.h> functions isalpha, isdigit, toupper, tolower and friends.

Characters Are Just Small Integers

Every char holds a number — its ASCII code. That is why comparisons, arithmetic, and array indexing all work on characters:

Example01
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 char s[] = "Hello";
6 int i;
7 
8 for (i = 0; s[i] != '\0'; i++)
9 printf("s[%d] = '%c' ASCII %d\n", i, s[i], s[i]);
10 return 0;
11}
Output
s[0] = 'H'  ASCII 72
s[1] = 'e'  ASCII 101
s[2] = 'l'  ASCII 108
s[3] = 'l'  ASCII 108
s[4] = 'o'  ASCII 111

Reading and Writing by Index

Index a string exactly like any array. Both reads and writes are allowed on a char array:

Example02
CCode Cell
1#include <stdio.h>
2#include <string.h>
3 
4int main()
5{
6 char s[20] = "hello";
7 
8 printf("First: %c, Last: %c\n", s[0], s[strlen(s) - 1]);
9 
10 s[0] = 'H'; /* capitalise the first letter */
11 printf("After: %s\n", s);
12 
13 strcat(s, "!"); /* append a character properly */
14 printf("Final: %s\n", s);
15 return 0;
16}
Output
First: h, Last: o
After: Hello
Final: Hello!

The ctype.h Classification Functions

These return non-zero (true) when the character belongs to the category. Include <ctype.h> to use them:

FunctionTrue when the character isExample match
isalpha(c)A lettera–z, A–Z
isdigit(c)A digit0–9
isalnum(c)A letter or digita–z, A–Z, 0–9
isspace(c)Whitespacespace, \t, \n
isupper(c)UppercaseA–Z
islower(c)Lowercasea–z
ispunct(c)Punctuation! , . ?
Example03
CCode Cell
1#include <stdio.h>
2#include <ctype.h>
3 
4int main()
5{
6 char s[] = "Hi 42!";
7 int i;
8 
9 for (i = 0; s[i] != '\0'; i++)
10 printf("'%c' alpha=%d digit=%d space=%d punct=%d\n",
11 s[i],
12 isalpha(s[i]) ? 1 : 0,
13 isdigit(s[i]) ? 1 : 0,
14 isspace(s[i]) ? 1 : 0,
15 ispunct(s[i]) ? 1 : 0);
16 return 0;
17}
Output
'H' alpha=1 digit=0 space=0 punct=0
'i' alpha=1 digit=0 space=0 punct=0
' ' alpha=0 digit=0 space=1 punct=0
'4' alpha=0 digit=1 space=0 punct=0
'2' alpha=0 digit=1 space=0 punct=0
'!' alpha=0 digit=0 space=0 punct=1

Counting Character Categories

One pass through the string, one counter per category — the standard text-analysis pattern:

Example04
CCode Cell
1#include <stdio.h>
2#include <ctype.h>
3 
4int main()
5{
6 char s[] = "Hello World 123!";
7 int letters = 0, digits = 0, spaces = 0, others = 0;
8 int i;
9 
10 for (i = 0; s[i] != '\0'; i++)
11 {
12 if (isalpha(s[i])) letters++;
13 else if (isdigit(s[i])) digits++;
14 else if (isspace(s[i])) spaces++;
15 else others++;
16 }
17 
18 printf("Text : %s\n", s);
19 printf("Letters : %d\n", letters);
20 printf("Digits : %d\n", digits);
21 printf("Spaces : %d\n", spaces);
22 printf("Others : %d\n", others);
23 return 0;
24}
Output
Text    : Hello World 123!
Letters : 10
Digits  : 3
Spaces  : 2
Others  : 1

Case Conversion

toupper and tolower return the converted character. They do not change anything in place, so you must assign the result back:

Example05
CCode Cell
1#include <stdio.h>
2#include <ctype.h>
3 
4int main()
5{
6 char s[] = "Hello World";
7 char upper[20], lower[20];
8 int i;
9 
10 for (i = 0; s[i] != '\0'; i++)
11 {
12 upper[i] = toupper(s[i]);
13 lower[i] = tolower(s[i]);
14 }
15 upper[i] = '\0'; /* terminate both copies */
16 lower[i] = '\0';
17 
18 printf("Original : %s\n", s);
19 printf("Upper : %s\n", upper);
20 printf("Lower : %s\n", lower);
21 return 0;
22}
Output
Original : Hello World
Upper    : HELLO WORLD
Lower    : hello world

Converting In Place

To change the original string, assign the result back into the same slot:

Example06
CCode Cell
1#include <stdio.h>
2#include <ctype.h>
3 
4int main()
5{
6 char s[] = "hello world";
7 int i;
8 
9 /* toupper(s[i]); WRONG - result thrown away */
10 
11 for (i = 0; s[i] != '\0'; i++)
12 s[i] = toupper(s[i]); /* correct */
13 
14 printf("%s\n", s);
15 return 0;
16}
Output
HELLO WORLD

Counting Vowels and Consonants

Normalise the case first, then a single comparison covers both cases:

Example07
CCode Cell
1#include <stdio.h>
2#include <ctype.h>
3 
4int main()
5{
6 char s[] = "Programming in C";
7 int vowels = 0, consonants = 0;
8 int i;
9 char c;
10 
11 for (i = 0; s[i] != '\0'; i++)
12 {
13 if (!isalpha(s[i])) continue;
14 
15 c = tolower(s[i]);
16 if (c=='a' || c=='e' || c=='i' || c=='o' || c=='u') vowels++;
17 else consonants++;
18 }
19 
20 printf("Vowels : %d\n", vowels);
21 printf("Consonants : %d\n", consonants);
22 return 0;
23}
Output
Vowels     : 5
Consonants : 9

Digit Characters to Numbers

Because digits sit consecutively in ASCII, subtracting '0' converts a digit character to its value:

Example08
CCode Cell
1#include <stdio.h>
2#include <ctype.h>
3 
4int main()
5{
6 char s[] = "a1b2c3";
7 int sum = 0, i;
8 
9 for (i = 0; s[i] != '\0'; i++)
10 if (isdigit(s[i]))
11 sum += s[i] - '0'; /* '3' - '0' = 3 */
12 
13 printf("Sum of digits in \"%s\" = %d\n", s, sum);
14 return 0;
15}
Output
Sum of digits in "a1b2c3" = 6

Title Case — A Practical Combination

Capitalise the first letter of each word by tracking whether the previous character was a space:

Example09
CCode Cell
1#include <stdio.h>
2#include <ctype.h>
3 
4int main()
5{
6 char s[] = "hello world from c";
7 int i, newWord = 1;
8 
9 for (i = 0; s[i] != '\0'; i++)
10 {
11 if (isspace(s[i]))
12 newWord = 1;
13 else if (newWord)
14 {
15 s[i] = toupper(s[i]);
16 newWord = 0;
17 }
18 }
19 
20 printf("%s\n", s);
21 return 0;
22}
Output
Hello World From C

Common Mistakes

  • Discarding the return valuetoupper(s[i]); does nothing on its own. Write s[i] = toupper(s[i]);.
  • Forgetting <ctype.h> — the code may still compile with warnings and behave oddly.
  • Comparing to a strings[i] == "a" compares a character to an address. Use 'a'.
  • Overwriting the terminator — building a new string and forgetting the final '\0'.
  • Assuming letters are contiguous'a' to 'z' is contiguous in ASCII, but comparing c >= 'a' && c <= 'z' is less portable than islower(c).
Trainer's Note: the ctype.h functions take an int and are defined for values representable as unsigned char plus EOF. With a plain char that happens to be signed, a byte above 127 becomes negative and the behaviour is undefined. In production code, cast: isalpha((unsigned char) s[i]).
📝 Key Takeaways
  • s[i] reads or writes the character at position i.
  • Include <ctype.h> for the is... and to... functions.
  • isalpha, isdigit, isspace, isupper, islower classify characters.
  • toupper and tolower return the converted character — they do not modify in place.
  • Characters are small integers, so arithmetic like s[i] - '0' works.

🧠 Test Your Knowledge

4 Questions
Progress: 0 / 4