문자열 데이터용 클래스
개요
이 페이지는 Qt의 문자열 클래스, 특히 다양한 문자열 컨테이너와 성능이 중요한 코드에서 이를 효율적으로 사용하는 방법에 대한 개요를 제공합니다.
다음의 효율적인 사용 지침은 상당한 양의 문자열 처리가 포함된, 성능이 중요한 코드를 다루는 숙련된 개발자를 대상으로 합니다. 예를 들어, 파서나 텍스트 파일 생성기 등이 이에 해당합니다. 일반적으로 ` QString `는 어디서나 사용할 수 있으며 성능도 양호합니다. 또한 여러 인코딩을 처리하기 위한 API(예: ` QString::fromLatin1()`)도 제공합니다. 많은 애플리케이션, 특히 문자열 처리가 성능에 미미한 영향을 미치는 경우, ` QString `는 간단하고 충분한 해결책이 될 것입니다. 일부 Qt 함수는 ` QStringView`를 반환합니다. 필요한 경우 ` QStringView::toString()`를 사용하여 이를 ` QString `로 변환할 수 있습니다.
효과적인 팁
다음 세 가지 규칙을 따르면 복잡성을 크게 늘리지 않으면서도 문자열 처리를 상당히 개선할 수 있습니다. 대부분의 경우에서 거의 최적의 성능을 얻으려면 이 규칙들을 따르십시오. 첫 번째와 두 번째 규칙은 문자열 리터럴의 인코딩과 소스 코드 내 표시에 관한 것입니다. 세 번째 규칙은 문자열의 일부를 사용할 때의 심층 복사에 관한 것입니다.
- ASCII 문자만 포함하는 모든 문자열(예: 로그 메시지)은 Latin-1로 인코딩할 수 있습니다. string literal
"foo"_L1를 사용하십시오. 이 접미사가 없으면 소스 코드의 문자열 리터럴은 UTF-8로 인코딩된 것으로 간주되어 처리 속도가 느려집니다. 일반적으로 가능한 한 가장 간결한 인코딩을 사용하도록 하십시오. 대부분의 경우 이는 Latin-1입니다. - 사용자에게 표시되는 문자열은 대개 번역되므로 QObject::tr() 함수를 통해 전달됩니다. 이 함수는 문자열 리터럴(const char 배열)을 받아 모든 UI 요소에서 요구하는 UTF-16 인코딩이 적용된 QString 를 반환합니다. 번역 인프라를 사용하지 않는 경우, 애플리케이션 전체에서 UTF-16 인코딩을 사용해야 합니다. UTF-16 문자열 리터럴을 생성하려면 문자열 리터럴 `
u"foo"`을 사용하거나, Qt 전용 리터럴 `u"foo"_s`을 사용하여 ` QString`을 직접 생성하십시오. - QString 의 일부를 처리할 때는 각 부분을 별도의 QString 객체로 복사하는 대신, QStringView 객체를 생성하십시오. 이 객체들은 QStringView::toString()을 사용하여 QString 로 다시 변환할 수 있지만, 가능한 한 이를 피하십시오. 함수가 QStringView 를 반환하는 경우, 가능하다면 이 클래스를 계속 사용하는 것이 가장 효율적입니다. 이 API는 상수 QString 와 유사합니다.
효율적인 사용법
문자열 클래스를 효율적으로 사용하려면 다음 세 가지 개념을 이해해야 합니다:
- 인코딩
- 소유형 및 비소유형 컨테이너
- 리터럴
인코딩
인코딩 측면에서 Qt는 UTF-16, UTF-8, Latin-1(ISO 8859-1) 및 US-ASCII(Latin-1과 UTF-8의 공통 부분집합)를 다양한 형태로 지원합니다.
- Latin-1은 문자당 1바이트를 사용하는 문자 인코딩으로, 가장 효율적이지만 제한도 있는 인코딩입니다.
- UTF-8은 모든 문자를 1~4바이트로 인코딩하는 가변 길이 문자 인코딩입니다. US-ASCII와 하위 호환되며, 소스 코드 및 유사한 파일에 일반적으로 사용되는 인코딩입니다. Qt는 소스 코드가 UTF-8로 인코딩되어 있다고 가정합니다.
- UTF-16은 문자당 2바이트 또는 4바이트를 사용하는 가변 길이 인코딩입니다. 이는 Qt에서 사용자에게 표시되는 텍스트에 일반적으로 사용되는 인코딩입니다.
자세한 내용은 Qt의 유니코드 지원에 대한 정보를 참조하십시오.
다른 인코딩은 ` QString::fromUcs4()`와 같은 단일 함수 형태나 ` QStringConverter ` 클래스 형태로 지원됩니다. 또한 Qt는 데이터 저장에 적합한 인코딩에 구애받지 않는 컨테이너인 ` QByteArray`를 제공하며, 이는 바이너리 데이터 저장에 특히 적합합니다. ` QAnyStringView `는 기본 문자열의 인코딩을 추적하므로, 지원되는 모든 인코딩 표준을 사용하는 문자열에 대한 뷰를 제공할 수 있습니다.
인코딩 간 변환은 처리 비용이 높으므로, 가능하면 피해야 합니다. 반면, 특히 문자열 리터럴의 경우 더 간결한 인코딩을 사용하면 바이너리 크기를 줄일 수 있어 성능 향상에 도움이 될 수 있습니다. 문자열 리터럴을 Latin-1로 표현할 수 있는 경우, 비록 어느 시점에서 UTF-16으로 변환되어야 하더라도 이러한 상충되는 요소들 사이에서 적절한 균형을 이룰 수 있습니다. Latin-1 문자열을 QString 로 변환해야 할 때는 비교적 효율적으로 처리됩니다.
기능
문자열 클래스는 지원하는 기능에 따라 더 세분화할 수 있습니다. 주요 구분 기준 중 하나는 데이터를 직접 소유(따라서 제어)하는지, 아니면 단순히 다른 곳에 저장된 데이터를 참조하는지에 있습니다. 전자를 소유형 컨테이너( owning containers)라고 하고, 후자를 비소유형 컨테이너( non-owning containers) 또는 뷰(views)라고 합니다. 비소유 컨테이너 유형은 일반적으로 데이터의 시작 위치에 대한 포인터와 데이터 크기만 기록하므로 가볍고 구현 비용이 적게 듭니다. 하지만 데이터가 사용 가능한 상태인 동안에만 유효합니다. 소유형 문자열은 데이터를 저장하는 메모리를 직접 관리하여 컨테이너의 수명 기간 내내 데이터가 사용 가능하도록 보장하지만, 생성 및 소멸 시 메모리 할당 및 해제 비용이 발생합니다. 뷰는 일반적으로 소유형 문자열 기능의 일부만 지원하며, 기본 데이터 자체를 수정할 수 없습니다.
결과적으로, 문자열 뷰는 파서와 같이 더 큰 문자열의 일부를 표현하는 데 특히 적합하며, 소유형 문자열은 클래스의 멤버와 같은 영구 저장소에 적합합니다. 함수가 조각들을 결합하는 등의 방식으로 직접 생성한 문자열을 반환하는 경우에는 소유 문자열을 반환해야 하지만, 함수가 영구적으로 저장된 문자열의 일부를 반환하는 경우에는 일반적으로 뷰가 더 적합합니다.
Qt의 소유 컨테이너는 데이터를 암시적으로 공유하므로, 참조 카운팅으로 인해 참조 전달보다 효율성은 약간 떨어지지만, 큰 컨테이너를 값으로 전달하거나 반환하는 것도 효율적이라는 점에 유의하십시오. Qt 클래스의 암시적 데이터 공유 메커니즘을 활용하려면, 문자열을 소유형 컨테이너나 그 참조로 전달해야 합니다. 뷰로 변환했다가 다시 되돌릴 경우, 항상 데이터의 추가 사본이 생성됩니다.
마지막으로, Qt는 단일 문자, 문자열 목록 및 문자열 매처용 클래스를 제공합니다. 이러한 클래스는 몇 가지 예외를 제외하고 Qt에서 지원되는 대부분의 인코딩 표준에서 사용할 수 있습니다. QLocale 이나 QTextBoundaryFinder 과 같은 특화된 클래스를 통해 더 높은 수준의 기능이 제공됩니다. 이러한 고수준 클래스는 대개 QString 와 그 UTF-16 인코딩을 기반으로 합니다. 일부 클래스는 템플릿이며 사용 가능한 모든 문자열 클래스와 함께 작동합니다.
리터럴
C++ 표준은 컴파일 시점에 문자열을 생성하기 위한 문자열 리터럴을 제공합니다. 언어에 의해 정의된 문자열 리터럴과 Qt에 의해 정의된 리터널, 즉 소위 사용자 정의 리터널이 있습니다. C++에 의해 정의된 문자열 리터럴은 큰따옴표로 묶여 있으며, 컴파일러가 그 내용을 어떻게 해석해야 하는지 알려주는 접두사를 가질 수 있습니다. Qt의 경우, UTF-16 문자열 리터럴 u"foo" 가 가장 중요합니다. 이는 컴파일 시점에 UTF-16으로 인코딩된 문자열을 생성하므로, 실행 시점에 다른 인코딩에서 변환할 필요가 없습니다. UTF-16 문자열 리터럴( QStringView )을 통해 `UTF-16` 인코딩을 가진 `UTF-16` 객체(`UTF-16`)를 쉽고 효율적으로 생성할 수 있으므로, ` QStringView ` 인수를 받는 함수(또는 결과적으로 ` QAnyStringView`)에 전달할 수 있습니다.
QString사용자 정의 리터럴은 C++에서 정의된 리터럴과 형식이 동일하지만, 닫는 따옴표 뒤에 접미사가 추가됩니다. 인코딩은 여전히 접두사에 의해 결정되지만, 결과 리터럴은 사용자 정의 타입의 객체를 생성하는 데 사용됩니다. u"foo"_s 의 경우 , QLatin1StringView 의 경우 "foo"_L1, QByteArray 의 경우 u"foo"_ba. 이들은 StringLiterals Namespace 를 사용하여 제공됩니다. 일반 C++ 문자열 리터럴 "foo" 는 UTF-8로 인식되므로, QString 로 변환하여 UTF-16으로 만드는 작업은 성능상 부담이 큽니다. 일반 ASCII 문자열 리터럴이 있는 경우, "foo"_L1 를 사용하여 이를 Latin-1로 해석하면 앞서 설명한 다양한 이점을 얻을 수 있습니다.
기본 문자열 클래스
다음 표는 다양한 텍스트 인코딩 표준에 대한 기본 문자열 클래스의 개요를 보여줍니다.
| 인코딩 | C++ 문자열 리터럴 | Qt 사용자 정의 리터럴 | C++ 문자 | Qt 문자 | 소유형 문자열 | 비소유 문자열 |
|---|---|---|---|---|---|---|
| Latin-1 | - | ""_L1 | - | QLatin1Char | - | QLatin1StringView |
| UTF-8 | u8"" | - | char8_t | - | - | QUtf8StringView |
| UTF-16 | u"" | u""_s | char16_t | QChar | QString | QStringView |
| 이진/없음 | - | ""_ba | std::byte | - | QByteArray | QByteArrayView |
| 유연 | any | - | - | - | - | QAnyStringView |
누락된 항목 중 일부는 내장형 및 표준 라이브러리 C++ 유형으로 대체할 수 있습니다. 소유권이 있는 Latin-1 또는 UTF-8 인코딩 문자열은 ` std::string `이거나, 어떤 8비트 ` char ` 배열이라도 될 수 있습니다. ` QStringView `은 또한 일부 플랫폼에서 `std::u16string`이나 `std::wstring`과 같은 16비트 문자 배열을 참조할 수도 있습니다.
Qt는 또한 QStringList 및 QByteArrayView 와 같은 일부 유형에 대한 특화된 리스트와, QLatin1StringMatcher 및 QByteArrayMatcher 와 같은 매처도 제공합니다. 매처에는 컴파일 시점에 생성되는 정적 버전인 QStaticLatin1StringMatcher 및 QStaticByteArrayMatcher 도 있습니다.
또한 주목할 점은:
- QStringLiteral 는
u"foo"_s과 동일하며, StringLiterals Namespace 없이도 사용할 수 있는 매크로입니다. 가급적이면 최신 문자열 리터럴을 사용하는 것이 좋습니다. - QLatin1String 는 QLatin1StringView 의 동의어이며, 하위 호환성을 위해 존재합니다. 이는 소유형 문자열이 아니며 향후 릴리스에서 제거될 수 있습니다.
- QAnyStringView 는 지원되는 세 가지 인코딩 중 하나를 사용하는 문자열에 대한 뷰를 제공합니다. 인코딩 정보는 데이터 참조와 함께 저장됩니다. 이 클래스는 다양한 문자열 유형과 인코딩을 수용하는 인터페이스를 생성하는 데 매우 적합합니다. 다른 클래스와 달리, QAnyStringView 에 대해서는 직접적인 처리가 수행되지 않습니다. 처리는 해당 인코딩의 기본 QLatin1StringView, QUtf8StringView 또는 QStringView 에 대해 수행됩니다. 이 클래스를 인수로 받는 사용자 정의 함수에서 동일한 작업을 수행하려면 QAnyStringView::visit()를 사용하십시오.
- UTF-8로 인코딩된 소스 코드 파일에서는 비-ASCII 문자가 포함된 QLatin1StringView 를 간단히 생성할 수 없으며, 특별한 처리가 필요합니다. 자세한 내용은 QLatin1StringView 문서를 참조하십시오.
- QStringRef 는 QString 의 일부를 참조하는 것으로, 하위 호환성을 위해 Qt5Compat 모듈에서 제공됩니다. 이는 QStringView 로 대체되어야 합니다.
고수준 문자열 관련 클래스
추가 기능을 제공하는 더 고수준의 클래스들은 대부분 QString 와 연동되며, 따라서 UTF-16을 사용합니다. 이러한 클래스는 다음과 같습니다:
- QRegularExpression, QRegularExpressionMatch 및 QRegularExpressionMatchIterator 는 패턴 매칭 및 정규식을 처리합니다.
- QLocale 사용자의 언어 및 문화에 적합한 방식으로 숫자와 데이터를 문자열로 변환하거나 문자열에서 숫자와 데이터로 변환합니다.
- QCollator 사용자의 언어, 문자 체계 또는 지역에 따라 문자열을 비교하는 QCollatorSortKey.
- QTextBoundaryFinder 유니코드 규칙에 따라 조판 준비가 된 텍스트를 분할합니다.
QStringBuilder+연산자를 사용한 문자열 연결 성능을 대폭 향상시켜 주는 내부 클래스인 에 대해서는 문서를 참조하십시오. QString
일부 클래스는 템플릿이거나 유연한 API를 갖추고 있어 다양한 문자열 클래스와 함께 작동합니다. 이러한 클래스는 다음과 같습니다.
- QTextStream QIODevice, 로 스트리밍하거나 QByteArray QString
- QStringTokenizer 문자열을 분할하기 위해
어떤 문자열 클래스를 사용해야 할까요?
문자열 클래스 사용에 대한 일반적인 지침은 다음과 같습니다.
- 복사 및 메모리 할당을 피하고,
- 인코딩 변환을 피하고,
- 가장 간결한 인코딩을 선택하십시오.
Qt는 메모리 할당을 피할 수 있는 다양한 기능을 제공합니다. 대부분의 Qt 컨테이너는 데이터에 대해 암시적 공유(Implicit Sharing )를 사용합니다. 암시적 공유가 제대로 작동하려면 동일한 클래스로 구성된 끊김 없는 체인이 존재해야 합니다. 즉, ` QString `에서 ` QStringView `로 변환했다가 다시 되돌리면, 데이터를 공유하지 않는 두 개의 ` QStrings `가 생성됩니다. 따라서 함수는 데이터를 QString 형태로 전달해야 합니다(값이나 참조 모두 가능). 암시적 데이터 공유 방식으로는 문자열의 일부를 추출할 수 없습니다. 긴 문자열의 일부를 사용하려면 명시적 데이터 공유 방식인 문자열 뷰(string views)를 활용하십시오.
특정 인코딩을 일관되게 사용하면 인코딩 간 변환을 줄일 수 있습니다. 예를 들어 UTF-8로 수신된 데이터는 다른 인코딩으로의 변환이 필요하지 않은 경우 UTF-8로 저장하고 처리하는 것이 가장 좋습니다. 동일한 인코딩을 가진 문자열 간의 비교는 가장 빠르며, 대부분의 다른 연산에서도 마찬가지입니다. 특정 인코딩의 문자열을 자주 비교하거나 다른 인코딩으로 변환해야 하는 경우, 한 번 변환하여 저장하는 것이 유리할 수 있습니다. 일부 연산에는 다양한 문자열 유형과 인코딩을 처리할 수 있는 여러 오버로드(또는 ` QAnyStringView ` 오버로드)가 제공되며, 동일한 인코딩을 사용하는 것이 불가능한 경우 성능 최적화를 위해 이를 두 번째 선택지로 고려해야 합니다. 함수를 호출하기 전에 명시적으로 인코딩을 변환하는 것은 다른 대안이 없을 때 최후의 수단으로만 사용해야 합니다. Latin-1은 매우 간단한 인코딩이며, Latin-1과 다른 인코딩 간의 연산은 동일한 인코딩 간의 연산만큼이나 효율적입니다.
인코딩을 결정하는 다른 제약 조건이 없는 경우, 가장 효율적인 인코딩(효율성이 높은 순서대로 Latin-1, UTF-8, UTF-16)을 선택해야 합니다. 오류 처리 및 로깅의 경우 일반적으로 ` QLatin1StringView `로 충분합니다. Qt에서 사용자에게 표시되는 문자열은 항상 ` QString ` 유형이며, 따라서 UTF-16으로 인코딩됩니다. 따라서 사용자에게 표시되는 문자열의 수명 주기 전반에 걸쳐 QStrings, QStringViews 및 QStringLiterals 를 사용하는 것이 가장 효과적입니다. QObject::tr() 함수는 올바른 인코딩과 유형을 제공합니다. 인코딩이 중요하지 않은 경우(예: 바이너리 데이터 저장 시)나 인코딩을 알 수 없는 경우에는 QByteArray 를 사용해야 합니다.
API 생성을 위한 String 클래스
멤버 변수
멤버 변수는 거의 모든 경우에 소유형(owning type)이어야 합니다. 뷰(View)는 참조되는 소유 문자열의 수명이 객체의 수명을 초과할 것이 보장되는 경우에만 멤버 변수로 사용할 수 있습니다.
함수 인자
함수 인수는 대부분의 경우 적절한 인코딩을 가진 문자열 뷰여야 합니다. 여러 인코딩을 지원하려면 ` QAnyStringView `를 매개변수로 사용할 수 있으며, 인코딩별 함수로 분기하려면 내부적으로 ` QAnyStringView::visit()`를 사용할 수 있습니다. 함수가 단일 인코딩으로 제한되는 경우, ` QLatin1StringView`, ` QUtf8StringView`, ` QStringView ` 또는 ` QByteArrayView `를 사용해야 합니다.
함수가 인수를 소유형 문자열(보통 세터 함수)에 저장하는 경우, Qt의 암시적 데이터 공유 기능을 활용하기 위해 동일한 소유형 문자열을 함수 인수로 사용하는 것이 가장 효율적입니다. 소유형 문자열은 ` const ` 참조로 전달할 수 있습니다. 소유형 및 비소유형 문자열 유형을 모두 사용하여 함수를 오버로딩하면 오버로드 모호성이 발생할 수 있으므로 피해야 합니다. Qt의 소유형 문자열 유형은 비소유형 버전이나 ` QAnyStringView`로 자동 변환될 수 있습니다.
반환 값
임시 문자열은 소유형 문자열(보통 ` QString`)로 반환되어야 합니다. 반환되는 문자열이 컴파일 시점에 알려진 경우, ` u"foo"_s `를 사용하여 컴파일 시점에 ` QString ` 구조체를 생성하십시오. 기존의 소유형 문자열(예: QString)이 함수에서 전체적으로 반환되는 경우(예: 게터 함수), 참조로 반환하는 것이 가장 효율적입니다. 또한 향후 임시 객체를 반환할 수 있도록 값으로 반환할 수도 있습니다. Qt의 암시적 공유(implicit sharing) 사용은 값으로 반환할 때 발생하는 할당 및 복사로 인한 성능 저하를 방지합니다.
기존 문자열의 일부는 적절한 인코딩을 가진 문자열 뷰를 사용하여 효율적으로 반환할 수 있습니다. 예를 들어, QStringView 를 반환하는 QRegularExpressionMatch::capturedView()을 참조하십시오.
API 사용을 위한 String 클래스
Qt API를 효율적으로 사용하려면 함수 인자 유형을 일치시키도록 노력해야 합니다. 선택의 폭이 제한적인 경우, Qt는 다양한 변환을 수행합니다. 소유형 문자열은 암시적으로 비소유형 문자열로 변환되며, 비소유형 문자열은 소유형 문자열을 생성할 수 있습니다. 예를 들어 QStringView::toString()을 참조하십시오. 인코딩 변환은 많은 경우 암시적으로 수행되지만, 가능하면 이를 피해야 합니다. UTF-8에서 의도치 않은 암시적 변환을 방지하려면 QT_NO_CAST_FROM_ASCII 매크로를 활성화할 수 있습니다.
실행 시점에 문자열을 조립한 후 함수에 전달해야 하는 경우, 소유 문자열이 필요하므로 QString 를 사용해야 합니다. 함수 인자가 QStringView 또는 QAnyStringView 인 경우 암시적으로 변환됩니다.
문자열이 컴파일 시점에 알려져 있다면 최적화의 여지가 있습니다. 함수가 QString 를 받아들이는 경우, u"foo"_s 또는 QStringLiteral 매크로를 사용하여 생성해야 합니다. 함수가 QStringView 를 기대하는 경우, 일반 UTF-16 문자열 리터럴 u"foo" 로 생성하는 것이 가장 좋으며, QLatin1StringView 를 기대하는 경우 "foo"_L1 로 생성하십시오. 두 가지 중에서 선택할 수 있는 경우(예: 함수가 QAnyStringView 를 기대하는 경우), 가장 엄격한 인코딩(일반적으로 Latin-1)을 사용하십시오.
모든 문자열 관련 클래스 목록
QString API의 읽기 전용 하위 집합을 사용하여 Latin-1, UTF-8 또는 UTF-16 문자열을 통합적으로 처리합니다 | |
바이트 배열 | |
바이트 배열 목록 | |
바이트 배열에서 빠르게 일치시킬 수 있는 일련의 바이트를 보관합니다 | |
QByteArray API의 읽기 전용 하위 집합을 사용하여 바이트 배열을 표시합니다. | |
16비트 유니코드 문자 | |
지역화된 정렬 알고리즘에 따라 문자열을 비교합니다. | |
문자열 정렬 속도를 높이는 데 사용할 수 있습니다 | |
8비트 ASCII/Latin-1 문자 | |
Latin-1 텍스트에서 부분 문자열을 검색하는 데 최적화됨 | |
US-ASCII/Latin-1로 인코딩된 문자열 리터럴을 감싸는 얇은 래퍼 | |
다양한 언어에서 숫자와 해당 숫자를 나타내는 문자열 간 변환 | |
정규 표현식을 사용한 패턴 매칭 | |
QRegularExpression을 문자열에 대조하여 얻은 결과 | |
QRegularExpression 객체가 문자열에 대해 전역 일치를 수행한 결과에 대한 이터레이터 | |
QByteArrayMatcher의 컴파일 타임 버전 | |
QLatin1StringMatcher의 컴파일 시간 버전 | |
유니코드 문자열 | |
텍스트 인코딩 및 디코딩을 위한 기본 클래스 | |
텍스트용 상태 기반 디코더 | |
텍스트용 상태 기반 인코더 | |
문자열 목록 | |
유니코드 문자열 내에서 빠르게 일치시킬 수 있는 일련의 문자를 보관합니다 | |
QString 부분 문자열을 감싸는 얇은 래퍼 | |
지정된 구분자를 따라 문자열을 토큰으로 분할합니다 | |
QString API의 읽기 전용 하위 집합을 사용하여 UTF-16 문자열을 통합적으로 처리합니다 | |
문자열 내에서 유니코드 텍스트 경계를 찾는 방법 | |
텍스트를 읽고 쓰는 데 편리한 인터페이스 | |
QString API의 읽기 전용 하위 집합을 통해 UTF-8 문자열을 통합적으로 처리 |
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.