2012-09-28 17 views
7
CString output ; 
const WCHAR* wc = L"Hellow World" ; 
if(wc != NULL) 
{ 
    output.Append(wc); 
} 
printf("output: %s\n",output.GetBuffer(0)); 
+0

Proszę dodać wyjaśnienie, jako czysty kod, niewiele mówi. – Kao

+0

Nie potrzebujesz GetBuffer. CString ma operator LPCTSTR, który uzyskuje dostęp do wewnętrznego bufora. – MikMik

+1

jaki powinien być wynik, jeśli 'wc' to' привет мир'? czy interesują cię strony kodowe czy jest to po prostu szeroka -> wąska konwersja z wszystkimi szerokimi znakami będącymi znakami ANSI? –

Odpowiedz

12

można również spróbować tego:

#include <comdef.h> // you will need this 
const WCHAR* wc = L"Hello World" ; 
_bstr_t b(wc); 
const char* c = b; 
printf("Output: %s\n", c); 

_bstr_t narzędzi następujące operatory konwersji, które uważam za przydatne:

operator const wchar_t*() const throw(); 
operator wchar_t*() const throw(); 
operator const char*() const; 
operator char*() const; 

EDYCJA: wyjaśnienie w odniesieniu do komentarzy do odpowiedzi: linia const char* c = b; powoduje utworzenie wąskiej kopii znaków ciągu tworzonego i zarządzanego przez instancję _bstr_t, która zwolni ją raz, gdy zostanie zniszczona. Operator zwraca tylko wskaźnik do tej kopii. Dlatego nie ma potrzeby kopiowania tego ciągu. Ponadto, w pytaniu, CString::GetBuffer zwraca LPTSTR (tj. TCHAR*) i nieLPCTSTR (tj. const TCHAR*).

Innym rozwiązaniem jest użycie makr przeliczeniowych:

USES_CONVERSION; 
const WCHAR* wc = L"Hello World" ; 
const char* c = W2A(wc); 

Problem z tego podejścia jest to, że pamięć o przebudowanej ciąg jest przydzielona na stosie, więc długość łańcucha jest ograniczona. Ta rodzina makr umożliwia jednak wybranie strony kodowej, która ma być użyta do konwersji, co jest często potrzebne, jeśli szeroki ciąg znaków zawiera znaki inne niż ANSI.

+0

Jestem tak kuszony, aby dać +1 temu. '_bstr_t' i' _variant_t' były moimi najlepszymi przyjaciółmi w czasach, kiedy naprawdę potrzebowałeś ATL do stworzenia przyzwoitego komponentu COM w C++ – sehe

+0

, ale nie skopiowałeś wc do c – jack

+0

, dlaczego miałbyś go skopiować? Twój kod pokazuje, że musisz go użyć w 'printf'. '_bstr_t' zajmie się zwolnieniem pamięci.Jeśli chcesz zachować kopię i wysłać ciąg znaków dookoła, użyj instancji '_bstr_t', a nie' const char * '- w tym sensie' _bstr_t' jest podobne do 'CString'. Dba o poprawne kopiowanie danych ciągu, gdy używane są wielokrotne kopie obiektu (chociaż nie używa * kopiowania na zapis *). –

1

Można to zrobić, czy można zrobić coś czystszego:

std::wcout << L"output: " << output.GetString() << std::endl; 
+1

Dlaczego użyć 'GetBuffer()'? Oto "GetString()" oficjalny getter C-stringów! – Rost

+0

@Rost copy-paste: D Nie musisz krzyczeć: D –

+2

Kopiuj i wklej to zło !!! Prawdziwi programiści zawsze wpisują char przez char! Nie wiesz?!? :-D – Rost

1

Jest to dość łatwe, ponieważ CString jest po prostu typedef dla CStringT, a także mieć dostęp do CStringA i CStringW (należy zapoznać się z dokumentacją na temat różnic).

CStringW myString = L"Hello World"; 
CString myConvertedString = myString; 
+0

'CStringA myConvertedString (L" Hello World ");' działa również – Rost

+0

Tak, zdaję sobie z tego sprawę, ale została napisana w ten sposób, aby być bliżej jego przykładowego kodu. –

+0

Co robi ta konwersja z szerokimi znakami, które nie mają pasującego wąskiego znaku? –

5

Można użyć do tego celu sprintf:

const char output[256]; 
const WCHAR* wc = L"Hellow World" ; 
sprintf(output, "%ws", wc); 
+0

Nie sądzę, że możesz zadeklarować 'output' jako' const' – CinCout

2

mój kod dla Linuksa

// Debian GNU/Linux 8 "Jessie" (amd64) 

#include <locale.h> 
#include <stdlib.h> 
#include <stdio.h> 

// Use wcstombs(3) to convert Unicode-string (wchar_t *) to UTF-8 (char *) 
// http://man7.org/linux/man-pages/man3/wcstombs.3.html 

int f(const wchar_t *wcs) { 
     setlocale(LC_ALL,"ru_RU.UTF-8"); 
     printf("Sizeof wchar_t: %d\n", sizeof(wchar_t)); 
     // on Windows, UTF-16 is internal Unicode encoding (UCS2 before WinXP) 
     // on Linux, UCS4 is internal Unicode encoding 
     for (int i = 0; wcs[i] > 0; i++) printf("%2d %08X\n",i,wcs[i]); 
     char s[256]; 
     size_t len = wcstombs(s,wcs,sizeof(s)); 
     if (len > 0) { 
       s[len] = '\0'; 
       printf("mbs: %s\n",s); 
       for (int i = 0; i < len; i++) 
         printf("%2d %02X\n",i,(unsigned char)s[i]); 
       printf("Size of mbs, in bytes: %d\n",len); 
       return 0; 
     } 
     else return -1; 
} 

int main() { 
     f(L"Привет"); // 6 symbols 
     return 0; 
} 

Jak zbudować

#!/bin/sh 
NAME=`basename $0 .sh` 
CC=/usr/bin/g++-4.9 
INCS="-I." 
LIBS="-L." 
$CC ${NAME}.c -o _${NAME} $INCS $LIBS 

Wyjście

$ ./_test 
Sizeof wchar_t: 4 
0 0000041F 
1 00000440 
2 00000438 
3 00000432 
4 00000435 
5 00000442 
mbs: Привет 
0 D0 
1 9F 
2 D1 
3 80 
4 D0 
5 B8 
6 D0 
7 B2 
8 D0 
9 B5 
10 D1 
11 82 
Size of mbs, in bytes: 12 
Powiązane problemy