Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C 언어로 각 단어의 첫 글자를 대문자로 변환하는 프로그램


대소문자가 섞여 있는 문자열이 주어졌을 때, 각 단어의 첫 문자는 대문자로, 나머지 문자는 모두 소문자로 변환하는 것이 이번 글의 목표입니다.

간단한 예시를 통해 개념을 자세히 살펴보겠습니다.

예를 들어 문자열 “hElLo world”가 주어진 경우, 첫 문자 'h'를 대문자 'H'로 바꾸고, 공백이나 문자열 끝 앞까지의 나머지 모든 문자는 소문자로 변환해야 합니다.

또한 공백 다음에 등장하는 첫 번째 문자 역시 대문자로 변환해야 합니다.

예제

입력: str[] = {"heLlO wORLD"}
출력: Hello World

입력: str[] = {"sUNIDHi bAnSAL"}
출력: Sunidhi Bansal

접근 방식

  • 이 문제는 문자의 ASCII 값을 활용하여 해결합니다.
  • ASCII(American Standard Code for Information Interchange)는 모든 문자에 고유한 코드 값이 할당되어 있음을 의미합니다. 대문자 A~Z는 65~90, 소문자 a~z는 97~122의 숫자 값을 가지며, 이 값들의 차이를 이용하면 대소문자 변환이 가능합니다.
  • 전체 문자열을 처음부터 끝까지 순회하면서 다음 작업을 수행합니다.
  • 현재 문자가 첫 번째 문자이거나 공백 바로 뒤에 오는 문자라면, 해당 문자가 a~z 범위(소문자)에 속하는지 확인합니다. 속한다면 'A'와 'a'의 ASCII 값 차이를 더해 대문자로 변환합니다.
  • 첫 번째 문자나 공백 직후의 문자가 아니라면, 해당 문자가 대문자(A~Z 범위)인지 검사하고, 맞다면 'a'와 'A'의 차이를 더해 소문자로 변환합니다.

알고리즘

시작
함수 int firstupper(char str[], int n)
    단계 1 -> 정수형 변수 i 선언
    단계 2 -> 반복문: i = 0부터 i < n까지 i를 1씩 증가시키며 실행
        만약 (i == 0 && str[i] != ' ') || (str[i] != ' ' && str[i-1] == ' ')이라면,
            만약 str[i] >= 'a' && str[i] <= 'z'라면,
                str[i] = (char)(('A'-'a') + str[i])
            조건문 종료
            아니고 만약 str[i] >= 'A' && str[i] <= 'Z'라면,
                str[i] = (char)(str[i] + ('a' - 'A'))
            조건문 종료
    함수 종료
함수 int main(int argc, char const *argv[])
    단계 1 -> char str[] = {"sUNIDHi bAnSAL"} 선언 및 초기화
    단계 2 -> 정수형 n을 sizeof(str)/sizeof(str[0]) 값으로 선언
    단계 3 -> firstupper(str, n) 호출
    단계 4 -> printf("%s\n", str)으로 결과 출력
main 함수 종료

C 코드 구현

#include <stdio.h>
int firstupper(char str[], int n) {
    int i;
    for(i = 0; i<n; i++) {
        if (i == 0 && str[i] != ' ' || str[i] != ' ' && str[i-1] == ' ') {
            if(str[i] >= 'a' && str[i]<='z') {
                str[i] = (char)(('A'-'a') + str[i]);
            }
        } else if (str[i] >= 'A' && str[i] <= 'Z') {
            str[i] = (char)(str[i] + ('a' - 'A'));
        }
    }
    return 0;
}
int main(int argc, char const *argv[]) {
    char str[] = {"sUNIDHi bAnSAL"};
    int n = sizeof(str)/sizeof(str[0]);
    firstupper(str, n);
    printf("%s\n", str);
    return 0;
}

실행 결과

Sunidhi Bansal

코드 설명

핵심은 ASCII 값의 차이를 활용하는 것입니다. 아스키 코드에서 대문자와 소문자는 항상 32만큼 차이가 납니다. 예를 들어 'a'(97)에서 'A'(65)를 빼면 -32가 되는데, 소문자에 이 값을 더하면 대응되는 대문자로 바뀝니다. 반대로 대문자에 +32를 더하면 소문자가 됩니다.

조건문 (i == 0 && str[i] != ' ') || (str[i] != ' ' && str[i-1] == ' ')은 현재 문자가 문자열의 맨 앞이거나 공백 바로 뒤에 위치하는지를 판별합니다. 해당 위치의 문자는 대문자화를 시도하고, 그 외 위치의 문자는 모두 소문자로 변환됩니다.

이 알고리즘은 문자열을 한 번만 순회하므로 시간 복잡도는 O(n)이며, 별도의 추가 배열 없이 입력 배열 자체를 수정하는 제자리(in-place) 방식으로 동작합니다.