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

Si prega di aggiungere una spiegazione, come codice puro, non dice molto. – Kao

+0

Non hai bisogno di GetBuffer. CString ha un operatore LPCTSTR che accede al buffer interno. – MikMik

+1

quale dovrebbe essere l'output se 'wc' è' привет мир'? ti interessa le code page o questa è solo ampia -> conversione stretta con tutti i caratteri ampi che sono caratteri ANSI? –

risposta

12

si può anche provare questo:

#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 attrezzi seguendo gli operatori di conversione, che trovo abbastanza utile:

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

MODIFICA: chiarimento in merito ai commenti di risposta: la riga const char* c = b; produce una copia a caratteri stretti della stringa creata e gestita dall'istanza _bstr_t che la rilascia una volta quando viene distrutta. L'operatore restituisce semplicemente un puntatore a questa copia. Pertanto, non è necessario copiare questa stringa. Inoltre, nella domanda, CString::GetBuffer restituisce LPTSTR (ad esempio TCHAR*) e nonLPCTSTR (ad esempio const TCHAR*).

Un'altra opzione è quella di utilizzare macro di conversione:

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

Il problema con questo approccio è che la memoria di stringa convertita viene allocata sulla pila, in modo che la lunghezza della stringa è limitata. Tuttavia, questa famiglia di macro di conversione consente di selezionare la tabella codici da utilizzare per la conversione, che è spesso necessaria se la stringa ampia contiene caratteri non ANSI.

+0

Sono così tentato di fare +1 su questo. '_bstr_t' e' _variant_t' erano i miei migliori amici ai tempi in cui avevi davvero bisogno di ATL per fare un buon componente COM in C++ – sehe

+0

ma non ha copiato il wc in c – jack

+0

perché dovrebbe copiarlo? il tuo codice mostra solo che devi usarlo in 'printf'. '_bstr_t' si occuperà di rilasciare la memoria.Se è necessario mantenere una copia e inviare la stringa, utilizzare l'istanza '_bstr_t', non' const char * '- in questo senso,' _bstr_t' è simile a 'CString'. Si occupa di copiare i dati di stringa correttamente quando vengono utilizzate più copie dell'oggetto (anche se non usa * copy-on-write *). –

1

Si potrebbe fare questo, o si potrebbe fare qualcosa di più pulito:

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

Perché usare 'GetBuffer()'? Ecco il getter ufficiale di 'GetString()' C! – Rost

+0

@Rost copia-incolla: D Non c'è bisogno di urlare: D –

+2

Copia-incolla è male !!! I veri sviluppatori reinseriscono sempre char in char! Non lo sai?!? :-D – Rost

1

E 'abbastanza facile, perché CString è solo un typedef per CStringT, e si ha anche accesso a CStringA e CStringW (si dovrebbe leggere la documentazione sulle differenze).

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

'CStringA myConvertedString (L" Hello World ");' funziona anche – Rost

+0

Sì, me ne rendo conto, ma è stato scritto in questo modo per essere più vicino al suo codice di esempio. –

+0

Che cosa fa questa conversione con caratteri grandi che non hanno un carattere stretto corrispondente? –

5

È possibile utilizzare sprintf per questo scopo:

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

Non penso che si possa dichiarare 'output' come' const' – CinCout

2

Il mio codice per Linux

// 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; 
} 

Come costruire

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

uscita

$ ./_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 
Problemi correlati