string
? wstring
?
std::string
A는 basic_string
A의 템플릿 char
, 및 std::wstring
A의 wchar_t
.
char
vs. wchar_t
char
문자, 보통 8 비트 문자를 포함해야합니다.
wchar_t
넓은 문자를 개최하기로하고, 일이 힘들 수있다 :
리눅스에,이 wchar_t
윈도우에, 그것은 2 바이트있는 동안, 4 바이트입니다.
그렇다면 유니 코드 는 어떻습니까?
문제는 유니 코드에 직접적으로 char
도 wchar_t
직접 연결되어 있지도 않습니다 .
리눅스에서?
리눅스 OS를 보자 : 우분투 시스템은 이미 유니 코드를 인식하고있다. char 문자열로 작업 할 때 기본적으로 UTF-8로 인코딩됩니다 (즉, 유니 코드 문자열). 다음 코드 :
#include <cstring>
#include <iostream>
int main(int argc, char* argv[])
{
const char text[] = "olé" ;
std::cout << "sizeof(char) : " << sizeof(char) << std::endl ;
std::cout << "text : " << text << std::endl ;
std::cout << "sizeof(text) : " << sizeof(text) << std::endl ;
std::cout << "strlen(text) : " << strlen(text) << std::endl ;
std::cout << "text(ordinals) :" ;
for(size_t i = 0, iMax = strlen(text); i < iMax; ++i)
{
std::cout << " " << static_cast<unsigned int>(
static_cast<unsigned char>(text[i])
);
}
std::cout << std::endl << std::endl ;
// - - -
const wchar_t wtext[] = L"olé" ;
std::cout << "sizeof(wchar_t) : " << sizeof(wchar_t) << std::endl ;
//std::cout << "wtext : " << wtext << std::endl ; <- error
std::cout << "wtext : UNABLE TO CONVERT NATIVELY." << std::endl ;
std::wcout << L"wtext : " << wtext << std::endl;
std::cout << "sizeof(wtext) : " << sizeof(wtext) << std::endl ;
std::cout << "wcslen(wtext) : " << wcslen(wtext) << std::endl ;
std::cout << "wtext(ordinals) :" ;
for(size_t i = 0, iMax = wcslen(wtext); i < iMax; ++i)
{
std::cout << " " << static_cast<unsigned int>(
static_cast<unsigned short>(wtext[i])
);
}
std::cout << std::endl << std::endl ;
return 0;
}
다음 텍스트를 출력합니다.
sizeof(char) : 1
text : olé
sizeof(text) : 5
strlen(text) : 4
text(ordinals) : 111 108 195 169
sizeof(wchar_t) : 4
wtext : UNABLE TO CONVERT NATIVELY.
wtext : ol�
sizeof(wtext) : 16
wcslen(wtext) : 3
wtext(ordinals) : 111 108 233
"olé"텍스트 char
는 실제로 110, 108, 195 및 169 (후행 0을 세지 않음)의 네 문자로 구성됩니다. ( wchar_t
코드를 연습으로 공부하도록하겠습니다 )
따라서 char
Linux에서 작업 할 때는 일반적으로 몰라도 유니 코드를 사용해야합니다. 와 함께 std::string
작동 char
하므로 std::string
이미 유니 코드 준비가되어 있습니다.
참고 std::string
는 C 문자열 API처럼 "올레"문자열을 고려할 것은 4 자,없는 세 가지가 있습니다. 따라서 UTF-8에서는 일부 문자 조합이 금지되므로 유니 코드 문자로 자르거나 재생할 때주의해야합니다.
Windows에서?
Windows에서는 약간 다릅니다. Win32에서 함께 응용 프로그램 작업을 많이 지원했다 char
다른에 캐릭터 세트 / 코드 페이지 유니 코드의 출현하기 전에, 전 세계에서 생산.
따라서 해결책은 흥미로 웠습니다. 응용 프로그램이에서 작동하는 char
경우 문자 스트링은 기계의 로컬 문자 세트 / 코드 페이지를 사용하여 GUI 레이블에 인코딩 / 인쇄 / 표시됩니다. 예를 들어 프랑스어로 지역화 된 Windows에서는 "olé"가 "olé"이지만 키릴 지역화 된 Windows ( Windows-1251 을 사용하는 경우 "olй")에서는 다릅니다 . 따라서 "역사 앱"은 일반적으로 이전과 동일하게 작동합니다.
유니 코드 기반 응용 프로그램의 경우 Windows wchar_t
는 2 바이트 너비의을 사용하고 UTF-16으로 인코딩됩니다. UTF-16 은 2 바이트 문자로 인코딩 된 유니 코드 (또는 대부분 가장 호환되는 UCS-2) 같은 것 IIRC).
사용 char
하는 응용 프로그램 은 "각 바이트가 하나 이상의 char
s 로 구성되어 있기 때문에" "멀티 바이트"라고 하며, 사용하는 응용 프로그램 wchar_t
은 "각 문자가 하나 또는 두 개로 구성되므로"widechar "라고 wchar_t
합니다. 자세한 내용은 MultiByteToWideChar 및 WideCharToMultiByte Win32 변환 API를 참조하십시오.
따라서 Windows에서 작업하는 경우 GTK + 또는 QT 와 같이 숨어있는 프레임 워크를 사용하지 않는 한 사용 하기 를 원치wchar_t
않습니다 . 사실, 뒤에서 Windows는 문자열로 작동 하므로 역사적인 응용 프로그램조차도 API 를 사용할 때 문자열이 변환됩니다 (Win32 GUI에서 레이블을 설정하는 저수준 API 기능).wchar_t
char
wchar_t
SetWindowText()
메모리 문제?
UTF-32는 문자 당 4 바이트이므로 UTF-8 텍스트와 UTF-16 텍스트 만 항상 UTF-32 텍스트보다 적거나 같은 양의 메모리를 사용하는 경우 추가 할 것이 많지 않습니다. ).
메모리 문제가있는 경우 대부분의 서구 언어보다 UTF-8 텍스트가 동일한 UTF-16 텍스트보다 적은 메모리를 사용합니다.
여전히 다른 언어 (중국어, 일본어 등)의 경우 사용되는 메모리는 UTF-16의 경우와 동일하거나 UTF-16의 경우 약간 더 큽니다.
대체로 UTF-16은 문자 당 2 바이트와 4 바이트를 주로 사용합니다 (특별한 언어 글리프 (Klingon? Elvish?)를 처리하지 않는 한 UTF-8은 1 ~ 4 바이트를 소비합니다.
자세한 내용은 http://en.wikipedia.org/wiki/UTF-8#Compared_to_UTF-16 을 참조하십시오 .
결론
std :: string보다 std :: wstring을 사용해야 할 때?
리눅스에서? 거의 없다 (§).
Windows에서? 거의 언제나 (§).
크로스 플랫폼 코드? 툴킷에 따라 ...
(§) : 툴킷 / 프레임 워크를 사용하지 않는 한
std::string
특수 문자를 포함한 모든 ASCII 문자 세트를 보유 할 수 있습니까 ?
주의 : A std::string
는 '이진'버퍼를 유지하는 데 적합합니다 std::wstring
.
리눅스에서? 예.
Windows에서? Windows 사용자의 현재 로캘에는 특수 문자 만 사용할 수 있습니다.
편집 ( Johann Gerell 의 주석 후 ) :
a std::string
는 모든 char
기반 문자열 을 처리하기에 충분합니다 (각각 char
0에서 255까지의 숫자 임). 그러나:
- ASCII는 0에서 127 사이 여야합니다. 더 높은
char
s는 ASCII가 아닙니다.
char
0에서 127까지 제대로 개최됩니다
char
128 ~ 255은 부호화 (유니, 유니 코드 등)에 따라 의미가되지만, 그들은 UTF-8 인코딩으로는 종일 유니 코드 글리프를 보유 할 수있을 것이다.
되어 std::wstring
거의 모든 인기있는 C ++ 컴파일러에 의해 지원?
주로 Windows로 포팅되는 GCC 기반 컴파일러는 예외입니다.
g ++ 4.3.2 (Linux)에서 작동하며 Visual C ++ 6 이후 Win32에서 유니 코드 API를 사용했습니다.
정확히 넓은 캐릭터는 무엇입니까?
C / C ++에서는 wchar_t
단순 char
문자 유형 보다 큰 문자 유형으로 작성되었습니다 . 유니 코드 글리프와 같은 인덱스가 255보다 큰 문자 (또는 127, ...에 따라 다름)에 넣는 데 사용됩니다.