C Program To Convert A String From Uppercase To Lowercase And Vice Versa
Converting the case of characters within a string is a common task in programming, essential for data normalization, validation, and presentation. In this article, you will learn how to convert a string from uppercase to lowercase, and from lowercase to uppercase, using standard C programming techniques.
Problem Statement
Strings often contain a mix of character cases due to various input sources, requiring normalization for consistent processing. For instance, user input might be "HELLO World" but needs to be "hello world" for search operations, or "product_id" might need to become "PRODUCT_ID" for database queries. The challenge is to efficiently iterate through a string and alter the case of each alphabetic character without affecting non-alphabetic characters.
Example
Consider the string "Hello World 123!".
- Converting to lowercase should yield: "hello world 123!"
- Converting to uppercase should yield: "HELLO WORLD 123!"
Background & Knowledge Prerequisites
To understand string case conversion in C, you should be familiar with:
- C Strings: How strings are represented as arrays of characters terminated by a null character (
'\0'). - Loops: Basic
fororwhileloops for iterating through characters. - ASCII Values: The American Standard Code for Information Interchange (ASCII) defines numerical values for characters, where uppercase and lowercase letters have a consistent difference (e.g., 'a' is 97, 'A' is 65;
97 - 65 = 32). - Standard C Libraries: Specifically,
for input/output andfor string manipulation, andfor character classification and conversion functions.
Use Cases or Case Studies
Here are practical applications where string case conversion is crucial:
- User Input Normalization: Converting all user search queries or usernames to a consistent case (e.g., lowercase) to ensure accurate matching, regardless of how the user typed it.
- Data Validation: Ensuring that specific fields (e.g., product codes, state abbreviations) adhere to a required case format (e.g., all uppercase) before storage.
- Case-Insensitive Comparisons: Before comparing two strings, converting both to the same case simplifies the comparison logic, making it case-insensitive.
- Text Formatting: Presenting text in a specific style, such as titles where the first letter of each word is uppercase, or display names that are entirely uppercase.
- Password Hashing/Security: While not directly related to security, standardizing case can be a pre-processing step before hashing, though case-sensitivity is often desired in actual passwords.
Solution Approaches
We will explore three common approaches to convert string cases in C.
Approach 1: Using tolower() and toupper() from
This approach leverages standard library functions designed specifically for character case conversion, offering a robust and portable solution.
One-line summary: Iterate through the string and apply tolower() or toupper() to each character.
// Case Conversion using ctype.h
#include <stdio.h>
#include <string.h> // For strlen
#include <ctype.h> // For tolower, toupper
// Function to convert string to lowercase
void toLowerCase(char *str) {
for (int i = 0; str[i] != '\\0'; i++) {
str[i] = tolower((unsigned char)str[i]);
}
}
// Function to convert string to uppercase
void toUpperCase(char *str) {
for (int i = 0; str[i] != '\\0'; i++) {
str[i] = toupper((unsigned char)str[i]);
}
}
int main() {
// Step 1: Define a string for conversion
char myString1[] = "Hello World 123!";
char myString2[] = "Another EXAMPLE String.";
char myString3[] = "miXeD cAsE.";
// Step 2: Convert to lowercase and print
printf("Original: \\"%s\\"\\n", myString1);
toLowerCase(myString1);
printf("Lowercase: \\"%s\\"\\n\\n", myString1);
// Step 3: Convert to uppercase and print
printf("Original: \\"%s\\"\\n", myString2);
toUpperCase(myString2);
printf("Uppercase: \\"%s\\"\\n\\n", myString2);
// Step 4: Demonstrate both conversions
printf("Original: \\"%s\\"\\n", myString3);
toLowerCase(myString3);
printf("Lowercase: \\"%s\\"\\n", myString3);
toUpperCase(myString3); // Convert the already lowercased string to uppercase
printf("Uppercase: \\"%s\\"\\n\\n", myString3);
return 0;
}
Sample Output:
Original: "Hello World 123!"
Lowercase: "hello world 123!"
Original: "Another EXAMPLE String."
Uppercase: "ANOTHER EXAMPLE STRING."
Original: "miXeD cAsE."
Lowercase: "mixed case."
Uppercase: "MIXED CASE."
Stepwise Explanation:
- Include Headers: Include
for printing,(thoughstrlenisn't strictly used inside the loops, it's common for string operations), and cruciallywhich providestolower()andtoupper(). toLowerCaseFunction:
- It takes a
char *str(a pointer to the string) as an argument, allowing the function to modify the original string in place. - A
forloop iterates through each character of the string until the null terminator'\0'is encountered. - Inside the loop,
tolower((unsigned char)str[i])converts the current characterstr[i]to its lowercase equivalent if it's an uppercase letter. The cast tounsigned charis important forctype.hfunctions to handle all possible character values correctly. Non-alphabetic characters remain unchanged. - The result is assigned back to
str[i], modifying the string in place.
toUpperCaseFunction: This function operates similarly totoLowerCase, but usestoupper()to convert characters to their uppercase equivalents.mainFunction: Demonstrates the usage by initializing a string and calling the conversion functions. The output confirms the in-place modifications.
Approach 2: Manual ASCII Conversion
This approach involves understanding the ASCII values of characters and manually adjusting them to convert their case. It can be useful for understanding underlying character representations.
One-line summary: Determine if a character is alphabetic and manually add/subtract 32 based on its current case.
// Case Conversion using Manual ASCII
#include <stdio.h>
// Function to convert string to lowercase using ASCII
void toLowerCase_ascii(char *str) {
for (int i = 0; str[i] != '\\0'; i++) {
// Check if the character is an uppercase letter (A-Z)
if (str[i] >= 'A' && str[i] <= 'Z') {
str[i] = str[i] + 32; // Add 32 to convert to lowercase
}
}
}
// Function to convert string to uppercase using ASCII
void toUpperCase_ascii(char *str) {
for (int i = 0; str[i] != '\\0'; i++) {
// Check if the character is a lowercase letter (a-z)
if (str[i] >= 'a' && str[i] <= 'z') {
str[i] = str[i] - 32; // Subtract 32 to convert to uppercase
}
}
}
int main() {
// Step 1: Define strings for conversion
char myString1[] = "Hello Manual World!";
char myString2[] = "cOdInG wItH aScIi.";
// Step 2: Convert to lowercase using ASCII and print
printf("Original: \\"%s\\"\\n", myString1);
toLowerCase_ascii(myString1);
printf("Lowercase (ASCII): \\"%s\\"\\n\\n", myString1);
// Step 3: Convert to uppercase using ASCII and print
printf("Original: \\"%s\\"\\n", myString2);
toUpperCase_ascii(myString2);
printf("Uppercase (ASCII): \\"%s\\"\\n\\n", myString2);
return 0;
}
Sample Output:
Original: "Hello Manual World!"
Lowercase (ASCII): "hello manual world!"
Original: "cOdInG wItH aScIi."
Uppercase (ASCII): "CODING WITH ASCII."
Stepwise Explanation:
- Include Headers: Only
is needed for this approach. toLowerCase_asciiFunction:
- It iterates through the string using a
forloop. - An
ifcondition(str[i] >= 'A' && str[i] <= 'Z')checks if the current character is an uppercase letter. This range check relies on the contiguous nature of uppercase letters in ASCII. - If it's an uppercase letter,
32is added to its ASCII value. This is because in ASCII, the lowercase version of a letter is exactly 32 greater than its uppercase counterpart (e.g., 'a' (97) - 'A' (65) = 32).
toUpperCase_asciiFunction:
- Similar logic, but it checks for lowercase letters (
'a'to'z'). - If a lowercase letter is found,
32is subtracted from its ASCII value to convert it to uppercase.
mainFunction: Sets up strings and calls the ASCII-based conversion functions.
Approach 3: Combined Case-Flipping Function
This approach demonstrates a function that can convert a string by flipping the case of each alphabetic character (uppercase to lowercase, lowercase to uppercase).
One-line summary: Iterate through the string and conditionally add or subtract 32 based on whether the character is currently uppercase or lowercase.
// Case-Flipping Function
#include <stdio.h>
#include <ctype.h> // For isupper, islower
// Function to flip the case of characters in a string
void flipCase(char *str) {
for (int i = 0; str[i] != '\\0'; i++) {
if (isupper((unsigned char)str[i])) {
str[i] = tolower((unsigned char)str[i]);
} else if (islower((unsigned char)str[i])) {
str[i] = toupper((unsigned char)str[i]);
}
// Non-alphabetic characters are left unchanged
}
}
int main() {
// Step 1: Define a string for case flipping
char myString[] = "Flip This String 123!";
// Step 2: Flip case and print
printf("Original: \\"%s\\"\\n", myString);
flipCase(myString);
printf("Flipped Case: \\"%s\\"\\n", myString);
return 0;
}
Sample Output:
Original: "Flip This String 123!"
Flipped Case: "fLIP tHIS sTRING 123!"
Stepwise Explanation:
- Include Headers: Includes
for output andforisupper(),islower(),tolower(), andtoupper(). flipCaseFunction:
- Iterates through each character of the string.
- It uses
isupper((unsigned char)str[i])to check if the current character is an uppercase letter. If true,tolower()converts it to lowercase. - If the character is not uppercase, it then checks
islower((unsigned char)str[i])to see if it's a lowercase letter. If true,toupper()converts it to uppercase. - Characters that are neither uppercase nor lowercase (e.g., numbers, symbols, spaces) are skipped, preserving their original form.
mainFunction: Initializes a string and demonstrates theflipCasefunction.
Conclusion
Converting string case in C is a fundamental string manipulation task with various methods available. The library functions (tolower, toupper) are generally preferred for their robustness, portability, and readability, as they handle locale-specific character sets better than manual ASCII arithmetic. However, understanding manual ASCII conversion provides valuable insight into character encoding. The combined case-flipping approach further illustrates how to achieve more dynamic case transformations.
Summary
-
ctype.hfunctions:tolower()andtoupper()are the standard and recommended way for case conversion, handling various character sets robustly. - Manual ASCII conversion: Involves adding or subtracting 32 from character ASCII values (
'A'to'Z'vs.'a'to'z'). This method is simple for basic ASCII but less portable. - In-place modification: All presented methods modify the string directly in memory.
- Non-alphabetic characters: These characters (numbers, symbols, spaces) are unaffected by case conversion functions.
-
unsigned charcast: Always cast the character to(unsigned char)before passing it toctype.hfunctions to avoid potential issues with negativecharvalues.