2013-02-10 1 views
0

x64 ArchLinux를 실행하는 QTCreator에 심각한 문제가 있습니다. 독일어 움라우트가 포함 된 명령 줄 매개 변수가 잘못되었습니다. std :: string으로 변환하고 싶습니다. 가능하면 적어도 이것에 대해 읽을 수 있습니다.독일어 움라우트에 대한 인코딩이 명령 줄 매개 변수

std::string arg(argv[1]); 
// do something with arg 

디버거를 사용하여 변수를 살펴보면 약간 이스케이프 된 문자열이 표시됩니다. 예를 들어, ä는 "= \"이됩니다. 그러나, 만약 내가

std::cout << arg << std::endl; 

내 콘솔 (urxvt)에 변수가 완전히 정상입니다.

QtCreator의 편집기 설정 (이전에 접촉하지 않은) 을 확인하고 UTF-8을 사용합니다. 내가 코멘트에 일부 움라우트를 추가 후 UTF-8로 원본 파일을 변환

% iconv -f ascii -t utf-8 main.cpp > _main.cpp 
% mv _main.cpp main.cpp 
# qtcreator recognized the change and ask me to reload the file, what I did 

% file -bi main.cpp 
# then results text/x-c; charset=utf-8, was text/x-c; charset=us-ascii before 

아무것도 일하지 실행. 심지어 움라우트를 포함하는 표준 : : 문자열을 정의 할 수 없습니다 :

std::string s("Mäx"); 
// the GDB debugger show 's' as: M=\x 

가 그럼 난

DEFINES += UNICODE 
# also without success 

더욱를 신비화하기 위해 내 .PRO 파일 내에서 유니 코드를 정의, 다음과 같은 다른있다 효과 :

std::vector<std::string> list(argv, argv + argc); 
# the debugger shows 2 elements (which is correct) 
# but the element at index 1 looks like this: "Mäx" 

전적으로 도움이 안됩니다. 어쩌면 누군가가 도울 수 있습니다. 감사

@Olaf : 2013

// lacks sanity checks but good enough for testing 
std::wstring Encoding::char2Wide(const char *chars) { 
    setlocale(LC_ALL, ""); 

    // get the length of the string to convert 
    int len = mbstowcs(NULL, chars, 0) + 1; 

    wchar_t* result = new wchar_t[len]; 
    len = mbstowcs(result, chars, len); 

    std::wstring s(result); 
    return s; 
} 

2월 11일는

조금을 명확히 은,이 그림은 표준의 문제 : 문자열 problem with std::string

출력을 보여줍니다 콘솔은 문제가 아닙니다. 괜찮아.

if (s == "Mäx") std::cout << "Yeahhh" << endl; 
-> Yeahhh (what the fxxx!) 

어쩌면 이것은 단지 qtcreator 문제입니다 : 여기

% locale 
LANG=de_DE.UTF-8 
LC_CTYPE="de_DE.UTF-8" 
LC_NUMERIC="de_DE.UTF-8" 
LC_TIME="de_DE.UTF-8" 
LC_COLLATE="de_DE.UTF-8" 
LC_MONETARY="de_DE.UTF-8" 
LC_MESSAGES="de_DE.UTF-8" 
LC_PAPER="de_DE.UTF-8" 
LC_NAME="de_DE.UTF-8" 
LC_ADDRESS="de_DE.UTF-8" 
LC_TELEPHONE="de_DE.UTF-8" 
LC_MEASUREMENT="de_DE.UTF-8" 
LC_IDENTIFICATION="de_DE.UTF-8" 
LC_ALL= 

하하 내 로케일 설정은 다음과 같습니다. 나는 Visual Studio로이 간단한 예제를 시도했으며 모두 예상대로 진행되었습니다. 그리고, 글쎄, 리눅스에서도 이클립스 CDT를 사용할 것으로 기대하고있다. GDB는 적절한 값을 보여줍니다. 나는 버그를 제기 할 것입니다.

UPDATE 정답 여기 https://stackoverflow.com/a/14801772/76591

보세요.

+0

그를 필요로 할 때 [Dietmar Kühl] (http://stackoverflow.com/users/1120273/dietmar-kuhl) 어디 있습니까? 그는 콘솔 앱에 대한 입력으로 자신의 f'ing * 이름 *을 입력 할 때마다 이것을 경험합니다. = P – WhozCraig

+0

사실 모든 것이 완벽하게 괜찮은 것처럼 들립니다. 올바른 값이 콘솔에 인쇄됩니다. 문제 해결됨. 디버거에서 볼 수있는 것은 UTF-8 바이트입니다. 그것은 예상된다. –

+0

@KonradRudolph 왜 디버거에서 UTF-8 바이트를 볼 것으로 예상됩니까? 내 시스템에서는 문자열을'M.xx '나'M = \ x'가 아닌 gdb에'Mx'로 표시합니다. –

답변

3

이것은 모두 다양한 프로그램에서 사용되는 인코딩 인 qtcreator, urxvt, gdb, ...에 따라 다릅니다.

모든 ASCII 파일이 이미 utf-8로 인코딩되어 있기 때문에 ascii에서 utf-8으로 변환하는 것은 의미가 없습니다. 첫 번째 127 utf-8 문자는 127 us-ascii 문자와 같습니다.

I는 GDB에서 std::string s("Mäx"); 보면 I 볼

(GDB) PS
$ 1 = {정적 비영리 = <는
_M_dataplus = {< 표준 : 할당 < CHAR>> 더 최적화 > = {< __gnu_cxx :: new_allocator < CHAR >> = {< 어떠한 데이터 필드 없음>} < 어떠한 데이터 필드 없음>} _M_p = 0x602028 "MAX"}}

귀하의 마지막 예제는

#하지만 인덱스 1의 요소는 다음과 같습니다 : "Mäx을"

출력이 iso-8859-1를 사용하여 보여줍니다에서 ä 때문에 UTF-8은 두 가지입니다 바이트 문자 303 244 8 진수. 이것을 man iso-8859-1으로 각각 표시 할 수 있습니다.

따라서 다양한 프로그램에서 서로 다른 출력이 표시되는 경우 이는 서로 다른 인코딩을 사용함을 의미합니다.

urxvt와 qtcreator라는 두 개의 프로그램이 있습니다.

에 따르면 qtcreator의 경우 프로젝트 설정에서 인코딩을 설정해야합니다.

urxvt의 경우 환경이 문제인 것처럼 보입니다. LANG=de_DE.UTF-8을 설정했는데, UTF-8 문자열에서 잘 작동합니다. 제가

urxvt

LANG = DE_DE urxvt로 시작한다면, 그것은 GDB 출력에 Mäx, 또는 "M\303\244x와 UTF-8 캐릭터 Mäx를 나타낸다. 당신이

LANG=en_US.UTF-8 urxvt 

또는

LANG=en_US urxvt 

으로 urxvt 시작하고 각각의 출력을 비교할 때

당신은 다른 동작을 테스트 할 수 있습니다.

업데이트 :

당신은 argv[1]에 마우스 오른쪽 버튼을 클릭하여 일반 C 문자열에 대한 표시를 변경할 수 있습니다 -> "변경 표시 형식"-> "UTF-8 문자열".

std::string 디스플레이의 경우 M=\x은 디버깅 도우미에서 제공됩니다. "도구"-> "옵션"-> "디버거"-> "디버깅 도우미"에서 디버깅 도우미를 비활성화했습니다.그런 다음 std::string의 개별 구성원을보고 _M_p을 변경하여 UTF-8 문자열도 표시 할 수 있습니다.

+0

흠, 인코딩에 관한 것이지만이를 해결하는 방법은 알지 못합니다.) 이상하게 생각합니다. Mäx의 두 가지 버전이 동일한 프로그램 런타임에 표시됩니다. 나는 성공적으로 char *를 std :: wstring으로 변환했다. 그러나 다시 이것을 std :: string으로 변환해야했다. – tfl

+0

@tfl'char *'을'std :: wstring'로'std :: string'으로 어떻게 변환 시켰습니까? –

+0

@tfl 방금 urxvt를 내 시스템 (Ubuntu 12.04)에 설치했는데'Mäx'를'Mäx'라고 표시하여 즉시 사용할 수있었습니다. –

0

main의 두 번째 인수로 wchar_t **를 사용하면됩니다.

+0

Linux에서 wchar_t 또는 std :: wstring을 사용하면 훨씬 더 혼란 스러울 수 있습니다. – tfl

관련 문제