문자 인코딩의 안개 - Qt 문자 인코딩

Qt 개발을 하는 과정에서 우리는 자주 중국어 부호화 문제에 부딪힌다. 인터넷에서 많은 방법을 제공하여 이 문제를 해결할 수 있지만 그들은 원리적으로 설명하지 않았다.이 글은 원리적으로 Qt 문자 인코딩의 문제를 명확하게 설명하고자 한다.
본문을 읽기 전에 인코딩의 기초 지식과 컴파일러가 문자 인코딩을 어떻게 처리하는지 파악해야 한다. 먼저 앞의 몇 편의 글을 읽어보자. 문자 인코딩의 안개를 벗기는 - 문자 인코딩의 안개를 벗기는 - 컴파일러가 파일 인코딩을 어떻게 처리하는지 개술한다.
우리는 “ -보고싶다-Test String.” 이 문자열로 설명하는데, 그것은 영어, 중국어, 한국어를 포함한다.제가 Qt를 사용하는 방식은 Visual Studio + Qt 라이브러리의 형식이기 때문에 본고는 Visual Studio의 MSVC 컴파일러를 예로 들어 설명하고자 합니다.
QString에서는 QChar를 사용하여 모든 문자를 저장합니다. QChar는 short 형식으로 2바이트를 차지하고 기본적으로 유니코드 인코딩으로 저장됩니다.
우선, 코드 파일에 쓴 테스트 문자열이 MSVC 컴파일러에 의해 이해될 수 있도록 원본 파일을 Utf8- 형식으로 저장해야 합니다.구체적인 참고: 문자 인코딩의 안개를 헤치고 - 컴파일러가 파일 인코딩을 어떻게 처리하는지
QString에 저장된 문자열의 인코딩 형식은 컴파일러 실행 문자 세트 인코딩 형식입니다.이 말은 매우 관건적이다.
MSVC에서 우리는 #pragma execution_character_set("utf-8")를 사용하여 이 원본 파일의 실행 문자 집합 인코딩 형식을 UTF8 형식으로 지정할 수 있다. 그러면 QString에 저장된 문자열 형식은utf8 인코딩이다.
다음은 완전한 테스트 용례입니다.

void Demo01::qStringUseCase() {
	/*
	      Utf8-BOM    .
	     UTF8-BOM.
	       UTF8:#pragma execution_character_set("utf-8")    stdafx.h.
	*/

#define TEST_STR_A "     -보고싶다-Test String."
#define TEST_STR_W L"     -보고싶다-Test String."

	{
		//          utf8,    OutputDebugStringA     ANSI
		OutputDebugStringA(Utf8ToAnsi(TEST_STR_A).c_str());
	}

	{
		ui.lblLanguage->setText(TEST_STR_A);
	}

	// char* --> QString
	{		
		QString qstr = TEST_STR_A;
		qInfo() << qstr;
	}

	// QString --> char* std::string
	{
		QString qstr = TEST_STR_A;

		std::string str = qstr.toStdString(); //       qstr.toStdString().c_str()   ,    qstr.toStdString()  std::string 
		const char* pStr = str.c_str();
		
		
		QString qstr2 = QString::fromUtf8(pStr);
		Q_ASSERT(qstr == qstr2);
	}

	// QString --> wchar_t* std::wstring
	{
		QString qstr = TEST_STR_A;

		std::wstring str = qstr.toStdWString();
		const wchar_t * pStr = str.c_str();

		QString qstr2 = QString::fromWCharArray(pStr);
		Q_ASSERT(qstr == qstr2);
	}

	// std::string --> QString
	{
		std::string str = TEST_STR_A;  // std::string     UTF-8      ,         UTF8
		QString qstr = QString::fromStdString(str);
	}

	// std::wstring --> QString
	{
		std::wstring str = TEST_STR_W;  // std::wstring     UTF-8      ,         UTF8
		QString qstr = QString::fromStdWString(str);
	}
}

QString 정보::toLocal8Bit
QString에는 toLocal8Bit라는 이름이 있는데, 인터넷에서 난자를 어떻게 해결하는지 소개하는 많은 글에서 이 함수를 언급한다.이 함수에 대한 공식 소개는 다음과 같다.
Returns the local 8-bit representation of the string as a QByteArray. The returned byte array is undefined if the string contains characters not supported by the local 8-bit encoding.

QTextCodec::codecForLocale() is used to perform the conversion from Unicode. If the locale encoding could not be determined, this function does the same as toLatin1().

If this string contains any characters that cannot be encoded in the locale, the returned byte array is undefined. Those characters may be suppressed or replaced by another.

간단하게 말하면 우리는 이 함수가 문자열을 ANSI 인코딩으로 변환하는 문자열을 이해할 수 있다. 문자 인코딩의 안개 - 문자 인코딩 개술 소개를 통해 ANSI가 구체적인 코드 페이지와 관련이 있다는 것을 알아야 한다(Windows 중국어 환경에서 기본적으로 인코딩 페이지 936).다만 Qt에서는 시스템 코드 페이지에 따라 판단하는 것이 아니라 QTextCodec를 통해 판단하기 때문에 문서에서 이 함수는 결합QTextCodec::codecForLocale()해서 사용하고 toLocal8Bit대응하는QTextCodec에 따라 상응하는 변환을 해야 한다고 언급한다.
총결산
따라서 Qt를 사용할 때 중국어 난자 문제가 발생하지 않도록 미리 컴파일된 헤더 파일에 다음과 같이 추가하면 됩니다.
#pragma execution_character_set("utf-8") 

일부 한글, 일본어 등 다른 국가의 문자는 Visual Studio의 기본 중국어 GB2312 인코딩에 없으므로 Visual Studio에서 "이 파일의 일부 유니코드 문자가 현재 코드 페이지에 저장되지 않았습니다"라는 메시지가 나타나면 "Utf8- "형식을 선택하여 저장하면 됩니다.
위에서 말한 바와 같이 원본 파일은 Utf8- 로 저장하고 설정#pragma execution_character_set("utf-8")을 하면 모든 난자를 해결할 수 있다.

좋은 웹페이지 즐겨찾기