Placement Prep

Toggle Each Character in a String: C, C++, Java, Python

C, C++, Java, and Python programs to toggle each character in a string. Covers the ASCII XOR bit-flip trick, isalpha() guard, and edge cases for placement coding tests.

By FACE Prep Team 5 min read
string-manipulation toggle-case c-programming java python dsa placement-prep

Toggling each character in a string means flipping its case: uppercase letters become lowercase, lowercase letters become uppercase, and everything else stays exactly as it is.

The classic example: input FacePrep, output fACEpREP. Each letter flips; no character is added or removed.

What Toggle-Case Means and Why Tests Use It

Toggle-case is a two-rule operation applied character by character:

  • If the character is uppercase, convert it to lowercase.
  • If the character is lowercase, convert it to uppercase.
  • If the character is a digit, space, or punctuation mark, leave it alone.

It appears in placement coding rounds for a direct reason: it tests whether a candidate understands character encoding, knows how to write a loop-with-conditional, and can name the time complexity without hesitation. TCS NQT coding sections, Infosys InfyTQ, and Wipro NLTH rounds have all featured variants of this problem as a warm-up question before more complex manipulations.

The follow-up that separates candidates is usually: “Can you do it without if-else?” That answer (the XOR trick) is covered in the next section.

For another character-by-character traversal problem that follows the same loop pattern, see finding the sum of digits and replacing characters conditionally.

The Logic: Standard Library vs. the ASCII XOR Trick

There are two approaches to flipping character case in C and C++.

Standard library approach

Use isupper() and islower() to test the character, then call tolower() or toupper() to convert. This is readable, portable, and locale-aware.

ASCII XOR trick

In standard ASCII, uppercase letters run from A (65) to Z (90) and lowercase letters run from a (97) to z (122). The difference between any letter and its opposite-case counterpart is exactly 32. In binary, 32 is 0010 0000, a single bit. Flipping bit 5 of any ASCII letter toggles its case.

CharacterASCIIBinaryAfter XOR 32Result
’A’650100 00010110 0001’a’ (97)
‘a’970110 00010100 0001’A’ (65)
‘F’700100 01100110 0110’f’ (102)
‘Z’900101 10100111 1010’z’ (122)

The operation is c ^= 32 (equivalently, c = c ^ 32).

The guard that cannot be skipped: XOR 32 is only valid for alphabetic characters. Apply it to ‘0’ (ASCII 48) and you get 16, a device-control character. Apply it to a space (ASCII 32) and you get 0, the null character. Every correct implementation wraps the XOR in isalpha(c).

C and C++ Implementations

C: standard library version

#include <stdio.h>
#include <ctype.h>
#include <string.h>

void toggleCase(char *str) {
    int n = strlen(str);
    for (int i = 0; i < n; 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-alpha characters unchanged */
    }
}

int main() {
    char str1[] = "FacePrep";
    toggleCase(str1);
    printf("%s\n", str1);            /* fACEpREP */

    char str2[] = "Hello World 123";
    toggleCase(str2);
    printf("%s\n", str2);            /* hELLO wORLD 123 */

    char str3[] = "";
    toggleCase(str3);
    printf("'%s'\n", str3);          /* '' (empty string passes cleanly) */

    return 0;
}

The (unsigned char) cast is standard practice when passing a char to <ctype.h> functions. The C standard says behaviour is undefined if the value is negative and not EOF; signed char on many platforms can hold negative values for characters above 127. The cast sidesteps that entirely.

The toupper / tolower reference on cppreference documents both functions and the cast requirement in detail.

C: XOR version

#include <stdio.h>
#include <ctype.h>
#include <string.h>

void toggleCaseXOR(char *str) {
    int n = strlen(str);
    for (int i = 0; i < n; i++) {
        if (isalpha((unsigned char)str[i]))
            str[i] ^= 32;   /* flip bit 5; valid only for a-z and A-Z */
    }
}

int main() {
    char str[] = "FacePrep";
    toggleCaseXOR(str);
    printf("%s\n", str);    /* fACEpREP */
    return 0;
}

Both C versions modify the string in-place. Space usage is O(1) auxiliary.

C++ version

#include <iostream>
#include <string>
#include <cctype>

std::string toggleCase(std::string s) {
    for (char &c : s) {
        if (std::isupper((unsigned char)c))
            c = std::tolower((unsigned char)c);
        else if (std::islower((unsigned char)c))
            c = std::toupper((unsigned char)c);
    }
    return s;   /* returns a toggled copy; original unchanged */
}

int main() {
    std::cout << toggleCase("FacePrep") << "\n";         // fACEpREP
    std::cout << toggleCase("Hello World 123") << "\n";  // hELLO wORLD 123
    return 0;
}

The range-for with a reference (char &c) means no index arithmetic and no risk of off-by-one.

Java Implementation

Java’s Character class provides isUpperCase(), isLowerCase(), toLowerCase(), and toUpperCase() as static methods. StringBuilder avoids the overhead of creating a new String object on every concatenation.

public class ToggleCase {
    public static String toggleCase(String s) {
        StringBuilder sb = new StringBuilder();
        for (char c : s.toCharArray()) {
            if (Character.isUpperCase(c))
                sb.append(Character.toLowerCase(c));
            else if (Character.isLowerCase(c))
                sb.append(Character.toUpperCase(c));
            else
                sb.append(c);   // digits, spaces, punctuation unchanged
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        System.out.println(toggleCase("FacePrep"));          // fACEpREP
        System.out.println(toggleCase("Hello World 123"));   // hELLO wORLD 123
        System.out.println(toggleCase(""));                  // (empty string)
        System.out.println(toggleCase("12345"));             // 12345 (all non-alpha)
    }
}

One interview follow-up worth knowing: String.toCharArray() allocates a new array; if memory is a concern on very large strings, you can use s.charAt(i) inside a traditional index loop instead.

Python Implementation

Python’s string type has a built-in method for this. According to the Python 3 documentation for str.swapcase(), it converts uppercase characters to lowercase and lowercase characters to uppercase, handling ASCII and Unicode characters correctly.

# Method 1: built-in swapcase()
def toggle_case(s):
    return s.swapcase()

print(toggle_case("FacePrep"))          # fACEpREP
print(toggle_case("Hello World 123"))   # hELLO wORLD 123
print(toggle_case(""))                  # (empty string)
print(toggle_case("12345"))             # 12345

For an interview where the examiner asks you to write it without a built-in:

# Method 2: manual loop
def toggle_case_manual(s):
    result = []
    for c in s:
        if c.isupper():
            result.append(c.lower())
        elif c.islower():
            result.append(c.upper())
        else:
            result.append(c)
    return ''.join(result)

print(toggle_case_manual("FacePrep"))   # fACEpREP

Using list.append() and a single ''.join() at the end is faster than string concatenation in a loop. String objects in Python are immutable; each + creates a new object. The list approach avoids that.

Edge Cases and Complexity

Every implementation above handles these four cases correctly:

  • Empty string: the loop body never executes; an empty string is returned or the original pointer is left as-is.
  • All uppercase: every character is flipped to lowercase. "FACEPREP" becomes "faceprep".
  • All lowercase: every character is flipped to uppercase. "faceprep" becomes "FACEPREP".
  • Non-alpha characters: digits, spaces, and punctuation marks pass through with no change. "Hello World 123" becomes "hELLO wORLD 123".

One edge case that catches candidates off guard: strings with characters above ASCII 127, such as accented letters or Unicode symbols. The C isupper() and islower() functions are locale-dependent; their behaviour on values outside the basic ASCII range is implementation-defined. Python’s swapcase() handles the full Unicode range correctly because it operates on Unicode code points, not raw bytes. Java’s Character.isUpperCase() is also Unicode-aware. For production C or C++ code that needs Unicode support, use a library such as ICU rather than the standard <ctype.h> functions.

Time complexity: O(n). Each character is visited exactly once. No nested loops, no sorting, no recursion. For a deeper look at how to analyse and state complexity for any solution you write in a placement round, see space complexity analysis.

Auxiliary space: O(1) for the in-place C and C++ implementations. O(n) for Java (StringBuilder builds a new string of length n) and Python (the returned string or list is length n).

The toggle-case pattern (one conditional branch per character, O(n) time) is the warm-up question in TCS NQT coding sections before the harder manipulations come in. Placement interviewers often follow it with: “can you eliminate the conditional entirely?” The XOR approach above is one answer. That same instinct for reasoning about characters at the bit level is what makes tokenizer internals and text preprocessing in LLM pipelines click faster when you get there. If you want to connect that instinct to actual model work, TinkerLLM is where those two levels meet, starting at ₹299.

Primary sources

Frequently asked questions

What does toggle case mean for a string?

Toggle case flips the case of every alphabetic character: uppercase letters become lowercase and lowercase letters become uppercase. Non-alphabetic characters such as digits, spaces, and punctuation are left unchanged.

Does the XOR trick work for non-alphabetic characters?

No. The bit-flip `c ^= 32` only produces correct results for ASCII letters A through Z and a through z. Applied to a digit like '0' (ASCII 48), XOR 32 gives 16, a device-control character. Always check `isalpha(c)` before applying the XOR flip.

What is the time complexity of the toggle-case program?

O(n), where n is the length of the string. Every character is visited exactly once. The in-place C and C++ versions also run in O(1) auxiliary space; Java and Python versions allocate a new string of length n, giving O(n) space.

How does Python swapcase() handle the toggle?

Python's built-in str.swapcase() iterates over every character and flips case using Unicode-aware rules. It handles ASCII letters, accented characters, and title-case characters correctly in one call without any guard conditions.

Which placement tests include toggle-case problems?

TCS NQT coding sections, Infosys InfyTQ practise tests, Wipro NLTH qualifier rounds, and Cognizant GenC aptitude tests all include character-manipulation problems in this category. They test conditional branching logic and character-encoding awareness.

Build AI projects

A self-paced playground for building with LLMs.

TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.

Try TinkerLLM (₹299 launch)
Free AI Roadmap PDF