들어가며
C++을 이용해서 UTF-8로 인코딩된 파일의 내용을 읽어와 콘솔창에 출력 할 때, 특히 윈도우의 경우 '?쒓??뚯뒪?' 처럼 텍스트가 깨져서 콘솔에 출력 된다. 기본적으로 유닉스 베이스 OS 콘솔은 코드페이지가 UTF-8을 지원하지만, 윈도우 콘솔은 기본 아스키 코드 페이지이기 때문에 SetConsoleOutputCP 함수를 이용해 프로그램과 연결된 콘솔의 코드페이지를 변경해주어야 한다.
※ SetConsoleOutputCP함수의 보다 자세한 사항은 [여기]를 참고하자.
Example
아래는 '한글테스트'라고 적혀 있는 utf-8로 인코딩 된 파일을 읽어와 출력하는 예제다.
NOTE : 티스토리 코드 블록 버그인지 아래 코드를 그대로 복붙해서 빌드하면 컴파일 에러가 발생하므로 첨부 파일을 다운 받아서 테스트 해보도록 하자.
#include <iostream>
#include <fstream>
#include <string>
#ifdef _WIN32
#include <Windows.h>
#endif
int main()
{
#ifdef _WIN32
SetConsoleOutputCP(CP_UTF8);
#endif
/** utf8.txt
한글테스트
*/
const std::string file_path = "utf8.txt";
std::ifstream is(file_path);
if (true == is.is_open())
{
std::string line;
while (getline(is, line))
{
std::cout << line << std::endl;
}
is.close();
}
}
Output
위 코드에서 11라인의 SetConsoleOutputCP를 주석 처리하고 컴파일 후 실행 하면 아래와 같은 결과가 출력된다.
?쒓??뚯뒪?
D:\helloworld_cpp\x64\Debug\helloworld_cpp.exe(프로세스 25400개)이(가) 종료되었습니다(코드: 0개).
이 창을 닫으려면 아무 키나 누르세요...
하지만 다시 주석을 제거하고 실행하게 된다면 아래와 같이 우리가 원하는 결과를 출력함을 볼수 있다.
한글테스트
D:\helloworld_cpp\x64\Debug\helloworld_cpp.exe(프로세스 20852개)이(가) 종료되었습니다(코드: 0개).
이 창을 닫으려면 아무 키나 누르세요...
NOTE
- 유닉스 베이스 OS의 콘솔에서는 별다른 처리가 없더라도 UTF-8 텍스트가 깨지지 않고 출력 된다.
- SetConsoleOutputCP는 윈도우 API다. OS 호환성을 위해서는 _WIN32와 같은 전처리가 필요하다.
- C++만 이런다. C#은 UTF-8이 잘 출력된다.
부록 1. 같이 읽으면 좋은 글
부록 2. 첨부 파일