한국어 English

Written By : Girish Ramakrishnan, ForwardBias Technologies

QString

The fundamentals of encoding are covered in BasicsOfStringEncoding [developer.qt.nokia.com].
인코딩에 대한 상세한 내용은 BasicsOfStringEncoding [developer.qt.nokia.com] 을 참조한다.

QString 은 유니코드 문자열을 저장한다. 정의상 QString 이 유니코드를 저장하기 때문에, 자신이 포함하는 내용들이 어떤 문자들로 구성되는지를 알고 있다. 이는 스스로 인코딩에 대한 정보가 없는 C 스타일 문자열(char *)과는 확연히 구분이 된다. QString 은 내부에 구성된 내용을 표시할 수 있는 글꼴만 존재한다며, 화면 또는 프린터 등으로 표시될 수 있다. Qt 에서의 모든 사용자가 인식가능한 문자열은 QString 으로 저장된다.

내부적으로는 QString 은 UTF-16 인코딩을 사용하여 문자열을 저장한다. UTF-16 의 각 2 바이트는 QChar 를 사용하여 표현된다. UTF-16 이 사용된 이유는 Mac OS X 및 Windows 환경하에서 네이티브 유니코드 API 를 사용할 경우 처리속도가 빠르기 때문이다.

C 스타일의 char 포인터형 및 바이트의 배열을 처리하기 위해서는 QString 대신 QByteArray 를 사용하여야 한다. UsingQByteArray [developer.qt.nokia.com] 을 참조한다.

C 스타일 문자열을 QString 과 함께 사용하기

  1.     QString string("Qt");

위의 소스코드가 입력 문자셋(input charset) 인코딩으로 임의파일에 저장되어 있다고 하자. 컴파일러는 C스타일의 문자열 “Qt” 를 메모리에 담는 실행 문자셋(exec charset) 의 어떤 다른 인코딩으로 된 코드를 생성하게 된다. 실행시에는, QString 은 이 메모리 주소를 가리키는 포인터를 얻게 되며, 이를 유니코드로 처리 및 변환하게 된다.

C스타일 문자열을 유니코드로 변환하기 위해서는, QString 은 실행 문자셋(exec charset)에 대해 알아야 한다. Qt 는 별다른 지정이 없다면, ASCII 로 이를 가정하여, 이 문자들을 Latin-1 (Ascii 와 Latin-1 은 상호호환된다) 로 디코딩을 시도한다. 따라서, Latin-1 문자들을 C 문자열에 굳이 담을 필요가 없는 것이다.

QTextCodec::setCodecForCStrings(실행 문자셋) 구문을 사용하면, C스타일 문자열을 디코딩할 때 Qt 가 사용하게될 인코딩 방법을 변경할 수 있다. 이 함수는 호출해 두면, QString::fromAscii() 함수를 통해, C 스타일 문자열을 지정한 새로운 문자셋을 사용해 디코딩할 수 있다.(즉, 더이상 fromAscii() 함수는 ASCII 디코딩을 하지 않는다).

QTextCodec::setCodecForCharCStrings 을 사용하는 단 한지 이유는 실행 문자셋(exec charset)이 ASCII 가 아닌 경우이다. 흔희, 소스코드 파일에 ASCII 가 아닌 문자열이 존재하게 되는 때 이런 경우가 생긴다. 이런 소스 파일은 UTF-8 로 저장되고, 컴파일러의 실행 문자셋(exec charset)이 UTF-8 로 지정하게 되는데, 이런 경우 QTextCodec::setCodecForCharCStrings(“UTF-8”) 을 실행한다면, Qt 는 모든 char * 포인터형이 가리키는 내용을 UTF-8 로 옳바르게 읽어들인다.

QTextCodec::setCodecForCStrings() 이 편리하기는 하지만, 소스파일에는 가능하다면, ASCII 문자들만 사용하는 것이 권장된다. 그 이유는 C++ 포준은 ASCII 지원을 은연중에 강조하고 있기 때문이기도 하고, 컴파일가 지원하는 인코딩이 어떤 것이어야 한다는 명확한 사양도 없기 때문이다. 만일, 문자열이 유로 문자(U+20AC)와 같은 문자를 포함하여야 한다면, 아래와 같은 방법들 중 하나를 생각해 볼 수 있다.

  1.     QString euro1 = QString::fromUtf8("\u20AC"); // the \u means Unicode sequence defined by c++ standard. \u encodes the codepoint in UTF-8
  2.     QString euro2 = QChar(0x20AC);
  3.     static const char utf8_euro[] = "\342\202\254"; // Euro symbol
  4.     QString euro3 = QString::fromUtf8(utf8_euro, sizeof(utf8_euro));

위의 방법을 쓰려면, 소스파일이 오직 ASCII 만으로 인코딩되어야 한다.

QString 의 유니코드 메소드

QChar 는 유니코드 한 글자를 표시한다. QString::unicode() 는 QString 의 QChar 배열(QChar*)을 반환한다. QString::utf16() 은 ushort*형 ushort배열을 반환한다. toUtf16()으로 *명명되지 않았음*에 유의하자. 그 이유는 QString 이 이미 UTF-16 이므로, 그 어떤 변환도 사실 필요하지 않기 때문이다.

QString::normalized() 은 유니코드 조합(composition) 및 분해(decomposition) 의 용도로도 사용될 수 도 있다.

QChar 는 항상 16비트의 값이다. 유니코드의 서로게이트 패어(Surrogate pair)는 2개의 QChar 로 표현된다. QChar::isHighSurrogate 및 QChar::isLowSurrogate 는 서로게이트 순서를 얻는데 사용할 수 있다. QChar::unicode() 는 이 값을 반환한다. QChar::cell() 및 QChar::row() 는 하위 바이트와 상위 바이트의 QChar를 얻는데 사용할 수 있다.

QString::length() 는 QChar 의 갯수를 얻을 때 사용된다. 따라서, 실제로는 이 갯수가 실제 문자의 갯수가 아닐 수 도 있다(문자열이 유니코드 보조 문자들을 표시하는 경우).

QString::toUtf8(), QString::fromUtf8(), QString::toUcs4(), QString::fromUcs4() 들은 UTF-8 및 UTF-32 로의 변환을 위한 함수들이다.

QString(char *) 을 통한 자동변환 막기

C스타일 문자열과 QString간의 자동 변환이 편리하지만, 써드파티 라이브러리를 사용할 때, 미묘한 버그를 유발 할 수 가 있다. Qt 는 C 스타일로 부터의 자동변환기능을 끌 수 있는 옵션을 제공한다. 예를 들어,

  1.     void gitCallback(const char *data)
  2.     {
  3.         QString string = data; // 컴파일 오류, 작성자로 하여금 'data'의 인코딩이 무엇인지 다시한번 생각하게 한다
  4.         ....
  5.     }

위의 컴파일 오류는 프로그래머로 하여금 QString의 사용을 재고하여(어쩌면 QByteArray를 쓰는 편이 더 나을 수 도 있다). C스타일 문자열의 인코딩이 무엇이었는지 알아내게 하려는 효과가 있다.

QT_NO_CAST_FROM_ASCII 매크로가 정의된 상태였다면, QString::fromAscii() 를 사용하여 C문자열 -> QString 의 변환이 자동으로 이루어지는 것을 막을 수 있으며, 컴파일 에러를 유발할 수 있다. 이제, 이 상수가 정의된 상태에서 위 코드는 아래와 같이 변경하여야 한다.

  1.     if (fruit== QString::fromUtf8("apple")) { ... } // 인코딩 방법을 명시한다

추가로 읽어볼 만한 내용

Using Qt Strings Effectively [developer.qt.nokia.com]

Categories: