TIL

[C++] 문자열 대소문자 변환 구현 및 탐색적 학습 방법론

think95592 2026. 5. 28. 20:54

학습 목표

  1. C++ 표준 라이브러리(std::string, <cctype>)를 활용한 문자열 대소문자 반전 기능을 구현할 수 있다.
  2. 아스키(ASCII) 코드 메커니즘을 이해하고, 내장 함수 없이 제어문과 연산자만으로 변환 로직을 설계할 수 있다.
  3. 지식 습득 과정에서 API 명세(Specification)와 동작 원리를 추적하는 올바른 엔지니어링 학습 습관을 형성한다.

1. 문제 정의 (Problem Statement)

사용자로부터 영문 알파벳으로 구성된 하나의 문자열을 입력받아, 대문자는 소문자로, 소문자는 대문자로 상호 변환하여 출력하는 프로그램을 작성하시오.

  • 입력 예시: aBcDe
  • 출력 예시: AbCdE

2. 핵심 이론 및 원리 (Core Concepts)

A. 아스키(ASCII) 코드와 문자의 정수 표현

컴퓨터 내부에서 모든 문자는 정수 형태의 부호로 저장됩니다. C++의 char 타입은 1바이트(8비트) 정수형 데이터 타입으로, 아스키 코드 표준을 따릅니다.

  • 대문자 'A'의 아스키 코드 값은 65이며, 소문자 'a'의 값은 97입니다.
  • 임의의 알파벳 문자에 대해 대문자와 소문자 간의 정수 차이는 항상 32입니다.
  •  
  • $$\text{소문자 아스키 값} - \text{대문자 아스키 값} = 32$$
  • 따라서 내장 함수가 없더라도 아스키 값에 32를 더하거나(+32) 빼는(-32) 산술 연산만으로 대소문자 전환이 가능합니다.

B. <cctype> 라이브러리의 주요 함수

C++은 문자 특성을 검사하고 변환하기 위한 헤더 파일 <cctype>을 제공합니다.

  • std::isupper(c): 문자 c가 대문자이면 참(비제외 값)을, 아니면 0을 반환합니다.
  • std::islower(c): 문자 c가 소문자이면 참(비제외 값)을, 아니면 0을 반환합니다.
  • std::toupper(c): 문자 c를 대문자로 변환하여 반환합니다.
  • std::tolower(c): 문자 c를 소문자로 변환하여 반환합니다.

3. 소스 코드 구현 (Implementation)

접근 방식 1: 표준 라이브러리 함수 활용 (추천 방식)

C++의 내장 함수와 참조자(&) 기반의 범위 기반 for 문(Range-based for loop)을 사용하여 문자열의 원본 값을 직접 변경하는 방식입니다.

C++
 
#include <iostream>
#include <string>
#include <cctype> // toupper, tolower, isupper 함수 사용을 위한 헤더

int main() {
    // 입출력 성능 최적화
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);

    std::string str;
    std::cin >> str;

    // 참조 변수(&)를 사용하여 문자열 내부의 각 문자를 직접 수정
    for (char &c : str) {
        if (std::isupper(c)) {
            c = std::tolower(c); // 대문자 -> 소문자
        } else if (std::islower(c)) {
            c = std::toupper(c); // 소문자 -> 대문자
        }
    }

    std::cout << str << "\n";

    return 0;
}

접근 방식 2: 아스키 코드 연산을 통한 직접 구현 (원리 이해)

표준 변환 함수를 기억하지 못하거나 라이브러리 사용이 제한된 환경에서, 아스키 코드의 수치적 특성을 이용해 조건문만으로 구현한 방식입니다.

C++
 
#include <iostream>
#include <string>

int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);

    std::string str;
    std::cin >> str;

    for (char &c : str) {
        // 대문자 범위 검사 ('A' = 65, 'Z' = 90)
        if (c >= 'A' && c <= 'Z') {
            c = c + 32; // 대문자에 32를 더하면 소문자가 됨
        }
        // 소문자 범위 검사 ('a' = 97, 'z' = 122)
        else if (c >= 'a' && c <= 'z') {
            c = c - 32; // 소문자에서 32를 빼면 대문자가 됨
        }
    }

    std::cout << str << "\n";

    return 0;
}