C++ Locale | "지역화" 가이드

C++ Locale | "지역화" 가이드

이 글의 핵심

C++ Locale에 대해 정리한 개발 블로그 글입니다. #include <locale> #include <iostream> using namespace std;

기본 사용법

#include <locale>
#include <iostream>
using namespace std;

int main() {
    // 현재 locale
    locale currentLocale;
    cout << currentLocale.name() << endl;
    
    // locale 설정
    locale::global(locale("ko_KR.UTF-8"));
    
    // 스트림에 적용
    cout.imbue(locale());
}

숫자 포매팅

#include <locale>
#include <iomanip>

int main() {
    // 천 단위 구분
    cout.imbue(locale("en_US.UTF-8"));
    cout << 1234567 << endl;  // 1,234,567
    
    // 통화
    cout << showbase << put_money(123456) << endl;  // $1,234.56
}

날짜/시간

#include <locale>
#include <iomanip>

int main() {
    auto now = chrono::system_clock::now();
    auto time = chrono::system_clock::to_time_t(now);
    
    // 한국어
    cout.imbue(locale("ko_KR.UTF-8"));
    cout << put_time(localtime(&time), "%c") << endl;
    
    // 영어
    cout.imbue(locale("en_US.UTF-8"));
    cout << put_time(localtime(&time), "%c") << endl;
}

실전 예시

예시 1: 다국어 메시지

#include <map>

class I18n {
private:
    map<string, map<string, string>> messages;
    string currentLang = "en";
    
public:
    void addMessage(const string& lang, const string& key, const string& value) {
        messages[lang][key] = value;
    }
    
    void setLanguage(const string& lang) {
        currentLang = lang;
    }
    
    string get(const string& key) const {
        auto langIt = messages.find(currentLang);
        if (langIt != messages.end()) {
            auto msgIt = langIt->second.find(key);
            if (msgIt != langIt->second.end()) {
                return msgIt->second;
            }
        }
        return key;  // 기본값
    }
};

int main() {
    I18n i18n;
    
    i18n.addMessage("en", "hello", "Hello");
    i18n.addMessage("en", "goodbye", "Goodbye");
    i18n.addMessage("ko", "hello", "안녕하세요");
    i18n.addMessage("ko", "goodbye", "안녕히 가세요");
    
    i18n.setLanguage("ko");
    cout << i18n.get("hello") << endl;
    cout << i18n.get("goodbye") << endl;
}

예시 2: 숫자 파싱

double parseNumber(const string& str, const locale& loc) {
    istringstream iss(str);
    iss.imbue(loc);
    
    double value;
    iss >> value;
    
    return value;
}

int main() {
    // 미국 형식
    double us = parseNumber("1,234.56", locale("en_US.UTF-8"));
    cout << us << endl;  // 1234.56
    
    // 유럽 형식
    double eu = parseNumber("1.234,56", locale("de_DE.UTF-8"));
    cout << eu << endl;  // 1234.56
}

예시 3: 문자 분류

#include <locale>

int main() {
    locale loc("en_US.UTF-8");
    
    char c = 'A';
    
    if (isalpha(c, loc)) {
        cout << c << "는 알파벳" << endl;
    }
    
    if (isupper(c, loc)) {
        cout << c << "는 대문자" << endl;
    }
    
    char lower = tolower(c, loc);
    cout << "소문자: " << lower << endl;  // a
}

통화 포매팅

#include <iomanip>

int main() {
    cout.imbue(locale("en_US.UTF-8"));
    cout << showbase << put_money(123456) << endl;  // $1,234.56
    
    cout.imbue(locale("ko_KR.UTF-8"));
    cout << showbase << put_money(123456) << endl;  // ₩123,456
}

자주 발생하는 문제

문제 1: locale 설치

// ❌ locale 없음
try {
    locale loc("ko_KR.UTF-8");
} catch (const runtime_error& e) {
    cout << "locale 없음" << endl;
}

// ✅ 시스템에 locale 설치
// Linux: locale-gen ko_KR.UTF-8
// macOS: 기본 설치됨

문제 2: 전역 locale 변경

// ❌ 전역 변경 (다른 코드 영향)
locale::global(locale("ko_KR.UTF-8"));

// ✅ 스트림별 설정
cout.imbue(locale("ko_KR.UTF-8"));

문제 3: 성능

// ❌ 매번 locale 생성
for (int i = 0; i < 1000; i++) {
    locale loc("en_US.UTF-8");  // 느림
    // ...
}

// ✅ 재사용
locale loc("en_US.UTF-8");
for (int i = 0; i < 1000; i++) {
    // ...
}

FAQ

Q1: locale은 언제 사용하나요?

A:

  • 다국어 지원
  • 숫자/날짜 형식
  • 통화 표시
  • 문자 분류

Q2: 성능 오버헤드는?

A: 약간 있습니다. 성능이 중요하면 직접 포매팅.

Q3: UTF-8 지원은?

A: C++20부터 개선. 이전 버전은 제한적.

Q4: 어떤 locale을 사용하나요?

A:

  • en_US.UTF-8 (미국)
  • ko_KR.UTF-8 (한국)
  • ja_JP.UTF-8 (일본)

Q5: locale 확인은?

A: locale -a 명령어로 확인.

Q6: locale 학습 리소스는?

A:

  • cppreference.com
  • “The C++ Standard Library”
  • ICU 라이브러리 문서

같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.

  • C++ string_view | “문자열 뷰” C++17 가이드
  • C++ Allocator | “메모리 할당자” 커스터마이징 가이드
  • C++ Chrono | “시간” 라이브러리 완벽 가이드

관련 글

  • 배열과 리스트 | 코딩 테스트 필수 자료구조 완벽 정리
  • C++ Adapter Pattern 완벽 가이드 | 인터페이스 변환과 호환성
  • C++ ADL |
  • C++ Aggregate Initialization |
  • C++ Aggregate Initialization 완벽 가이드 | 집합 초기화