std :: wstring VS std :: string

Non sono in grado di capire le differenze tra std::string e std::wstring . So che wstring supporta caratteri ampi come i caratteri Unicode. Ho le seguenti domande:

  1. Quando dovrei usare std::wstring su std::string ?
  2. Può std::string contenere l’intero set di caratteri ASCII, inclusi i caratteri speciali?
  3. std::wstring supportato da tutti i popolari compilatori C ++?
  4. Cos’è esattamente un ” ampio carattere “?

string ? wstring ?

std::string è una std::string basic_string su un char e std::wstring su un wchar_t .

char vs. wchar_t

char dovrebbe contenere un carattere, di solito un carattere da 1 byte. wchar_t dovrebbe contenere un carattere ampio e quindi le cose si complicano: su Linux, un wchar_t è 4 byte, mentre su Windows, sono 2 byte

che dire di Unicode , quindi?

Il problema è che né charwchar_t sono direttamente collegati all’unicode.

Su Linux?

Prendiamo un sistema operativo Linux: il mio sistema Ubuntu è già sensibile all’unicode. Quando lavoro con una stringa di caratteri, è codificata in modo nativo in UTF-8 (cioè una stringa di caratteri Unicode). Il seguente codice:

 #include  #include  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(bytes) :" ; for(size_t i = 0, iMax = strlen(text); i < iMax; ++i) { std::cout << " " << static_cast( static_cast(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(bytes) :" ; for(size_t i = 0, iMax = wcslen(wtext); i < iMax; ++i) { std::cout << " " << static_cast( static_cast(wtext[i]) ); } std::cout << std::endl << std::endl ; return 0; } 

emette il seguente testo:

 sizeof(char) : 1 text : olé sizeof(text) : 5 strlen(text) : 4 text(bytes) : 111 108 195 169 sizeof(wchar_t) : 4 wtext : UNABLE TO CONVERT NATIVELY. wtext : ol  sizeof(wtext) : 16 wcslen(wtext) : 3 wtext(bytes) : 111 108 233 

Vedrete che il testo "olé" in char è in realtà composto da quattro caratteri: 110, 108, 195 e 169 (senza contare lo zero finale). (Ti farò studiare il codice wchar_t come esercizio)

Quindi, quando si lavora con un char su Linux, di solito si finisce per usare Unicode senza nemmeno saperlo. E come std :: string funziona con char, quindi std :: string è già pronto per Unicode.

Nota che std :: string, come l'API della stringa C, considererà la stringa "olé" con 4 caratteri, non tre. Quindi dovresti essere cauto quando troncare / giocare con caratteri unicode perché una combinazione di caratteri è proibita in UTF-8.

Su Windows?

Su Windows, questo è un po 'diverso. Win32 doveva supportare molte applicazioni funzionanti con char e su diversi set di caratteri / codepage prodotti in tutto il mondo, prima dell'avvento di Unicode.

Quindi la loro soluzione era interessante: se un'applicazione funziona con char , le stringhe di caratteri vengono codificate / stampate / mostrate sulle etichette della GUI usando il set di caratteri / codepage locale sulla macchina. Ad esempio, "olé" sarebbe "olé" in un Windows localizzato in francese, ma sarebbe qualcosa di diverso su un Windows localizzato in cirillico ("ol" se si usa Windows-1251 ). Pertanto, le "app storiche" di solito funzionano sempre allo stesso modo.

Per le applicazioni basate su Unicode, Windows usa wchar_t , che è largo 2 byte, ed è codificato in UTF-16 , che è codificato in Unicode su caratteri da 2 byte (o per lo meno, l'UCS-2 per lo più compatibile, che è quasi la stessa cosa IIRC).

Le applicazioni che usano char sono dette "multibyte" (poiché ogni glifo è composto da uno o più char ), mentre le applicazioni che usano wchar_t sono dette "widechar" (poiché ciascun glifo è composto da uno o due wchar_t . Vedi API di conversione Win32 MultiByteToWideChar e WideCharToMultiByte per maggiori informazioni.

Quindi, se lavori su Windows, vuoi usare wchar_t (a meno che non usi un framework che nasconde quello, come GTK + o QT ...). Il fatto è che dietro le quinte, Windows funziona con le stringhe wchar_t , quindi anche le applicazioni storiche convertiranno le stringhe di char in wchar_t quando usano API come SetWindowText (funzione API di basso livello per impostare l'etichetta su una GUI Win32).

Problemi di memoria?

UTF-32 è 4 byte per caratteri, quindi non c'è molto da aggiungere, se solo un testo UTF-8 e un testo UTF-16 utilizzeranno sempre meno o la stessa quantità di memoria di un testo UTF-32 (e di solito meno ).

Se c'è un problema di memoria, allora dovresti sapere che rispetto alla maggior parte delle lingue occidentali, il testo UTF-8 userà meno memoria rispetto allo stesso UTF-16.

Tuttavia, per le altre lingue (cinese, giapponese, ecc.), La memoria utilizzata sarà uguale o più grande per UTF-8 che per UTF-16.

Tutto sumto, UTF-16 utilizzerà principalmente 2 byte per carattere (a meno che non abbiate a che fare con un qualche tipo di glifo del linguaggio esoterico (Klingon? Elvish?), Mentre UTF-8 passerà da 1 a 4 byte.

Vedi http://en.wikipedia.org/wiki/UTF-8#Compared_to_UTF-16 per maggiori informazioni.

Conclusione

1. Quando dovrei usare std :: wstring su std :: string?

Su Linux? Quasi mai (§).
Su Windows? Quasi sempre (§).
Nel codice multipiattaforma? Dipende dal tuo toolkit ...

(§): a meno che non si usi un toolkit / framework che dice diversamente

2. Can std :: string contiene tutto il set di caratteri ASCII compresi i caratteri speciali?

Nota: una stringa std :: è adatta per contenere un buffer 'binario', dove non è std :: wstring!

Su Linux? Sì.
Su Windows? Sono disponibili solo caratteri speciali per le impostazioni internazionali correnti dell'utente Windows.

Modifica (Dopo un commento di Johann Gerell ): una stringa std :: string sarà sufficiente per gestire tutte le stringhe basate su char (ogni char è un numero compreso tra 0 e 255). Ma:

  1. ASCII dovrebbe passare da 0 a 127. I caratteri più alti NON sono ASCII.
  2. un carattere da 0 a 127 verrà tenuto correttamente
  3. un carattere da 128 a 255 avrà un significato a seconda della codifica (unicode, non unicode, ecc.), ma sarà in grado di contenere tutti glifi Unicode purché codificati in UTF-8.

3. std: wstring è supportato da quasi tutti i popolari compilatori C ++?

Principalmente, ad eccezione dei compilatori basati su GCC portati su Windows
Funziona sul mio g ++ 4.3.2 (sotto Linux), e ho usato l'API Unicode su Win32 da Visual C ++ 6.

4. Che cos'è esattamente un personaggio ampio?

Su C / C ++, è un tipo di carattere scritto wchar_t che è più grande del semplice tipo di carattere char . Dovrebbe essere usato per mettere dentro i caratteri i cui indici (come glifi Unicode) sono più grandi di 255 (o 127, a seconda ...)

Raccomando di evitare std::wstring su Windows o altrove, tranne quando richiesto dall’interfaccia, o ovunque vicino alle chiamate API di Windows e alle rispettive conversioni di codifica come zucchero sintattico.

La mia opinione è riassunta in http://utf8everywhere.org di cui sono un co-autore.

A meno che la tua applicazione non sia incentrata sulla chiamata dell’API, ad esempio principalmente l’interfaccia utente, il suggerimento è di memorizzare stringhe Unicode in std :: string e codificate in UTF-8, eseguendo la conversione vicino alle chiamate API. I benefici delineati nell’articolo superano l’apparente fastidio della conversione, specialmente in applicazioni complesse. Questo è doppiamente così per lo sviluppo di librerie e piattaforms multiple.

E ora, rispondendo alle tue domande:

  1. Alcuni motivi deboli. Esiste per ragioni storiche, in cui si riteneva che widechar fosse il modo corretto di supportare Unicode. Ora è usato per interfacciare API che preferiscono le stringhe UTF-16. Li uso solo nelle immediate vicinanze di tali chiamate API.
  2. Questo non ha nulla a che fare con std :: string. Può contenere qualunque codifica tu inserisca. L’unica domanda è come tratti il ​​suo contenuto. La mia raccomandazione è UTF-8, quindi sarà in grado di contenere correttamente tutti i caratteri Unicode. È una pratica comune su Linux, ma penso che anche i programmi Windows dovrebbero farlo.
  3. No.
  4. Il carattere ampio è un nome confuso. Agli albori di Unicode, si credeva che il carattere potesse essere codificato in due byte, da cui il nome. Oggi rappresenta “qualsiasi parte del carattere lunga due byte”. L’UTF-16 è vista come una sequenza di tali coppie di byte (ovvero i caratteri Wide). Un personaggio in UTF-16 prende una o due coppie.

Quindi, ogni lettore qui ora dovrebbe avere una chiara comprensione dei fatti, della situazione. In caso contrario, è necessario leggere la risposta eccezionalmente completa di paercebal [btw: thanks!].

La mia conclusione pragmatica è sorprendentemente semplice: tutta quella roba “codifica caratteri” C ++ (e STL) è sostanzialmente rotta e inutile. Dai la colpa a Microsoft o no, che comunque non ti aiuterà.

La mia soluzione, dopo un’indagine approfondita, molta frustrazione e le conseguenti esperienze sono le seguenti:

  1. accetta, che devi essere responsabile da solo per la codifica e la conversione (e vedrai che gran parte di essa è piuttosto banale)

  2. usa std :: string per qualsiasi stringa codificata UTF-8 (solo un typedef std::string UTF8String )

  3. accetta che un object UTF8String sia solo un contenitore stupido ma economico. Non accedere mai e / o manipolare mai i caratteri direttamente (nessuna ricerca, sostituzione e così via). Potresti, ma davvero, davvero, non vuoi perdere tempo a scrivere algoritmi di manipolazione del testo per stringhe multi-byte! Anche se altre persone hanno già fatto cose così stupide, non farlo! Lascia fare! (Beh, ci sono scenari in cui ha senso … basta usare la libreria ICU per quelli).

  4. usa std :: wstring per stringhe codificate in UCS-2 ( typedef std::wstring UCS2String ) – questo è un compromesso e una concessione al pasticcio introdotto dall’API WIN32). UCS-2 è sufficiente per la maggior parte di noi (ne riparleremo più avanti …).

  5. utilizzare le istanze UCS2String ogni volta che è richiesto un accesso carattere per carattere (leggi, manipola e così via). Qualsiasi elaborazione basata sui caratteri dovrebbe essere eseguita in una rappresentazione NON multibyte. È semplice, veloce, facile.

  6. aggiungere due funzioni di utilità per convertire avanti e indietro tra UTF-8 e UCS-2:

     UCS2String ConvertToUCS2( const UTF8String &str ); UTF8String ConvertToUTF8( const UCS2String &str ); 

Le conversioni sono semplici, Google dovrebbe aiutare qui …

Questo è tutto. Usa UTF8String ovunque la memoria sia preziosa e per tutti gli I / O UTF-8. Utilizzare UCS2String ovunque sia necessario analizzare e / o manipolare la stringa. È ansible convertire tra queste due rappresentazioni in qualsiasi momento.

Alternative e miglioramenti

  • le conversioni da & a codifiche di caratteri a singolo byte (es. ISO-8859-1) possono essere realizzate con l’ausilio di semplici tabelle di conversione, ad esempio const wchar_t tt_iso88951[256] = {0,1,2,...}; e codice appropriato per la conversione in & da UCS2.

  • se UCS-2 non è sufficiente, passare a UCS-4 ( typedef std::basic_string UCS2String )

ICU o altre librerie Unicode?

Per cose avanzate.

  1. Quando vuoi inserire caratteri estesi nella tua stringa. wide dipende dall’implementazione. Visual C ++ imposta automaticamente a 16 bit se ricordo correttamente, mentre GCC si imposta in base alla destinazione. È lungo 32 bit qui. Si noti che wchar_t (tipo di carattere esteso) non ha nulla a che fare con unicode. È semplicemente garantito che è ansible memorizzare tutti i membri del set di caratteri più grande supportato dall’implementazione dalle sue localizzazioni e almeno fino a quando char. È ansible memorizzare stringhe unicode bene in std::string utilizzando anche la codifica utf-8 . Ma non capirà il significato dei punti di codice unicode. Quindi str.size() non ti darà la quantità di caratteri logici nella tua stringa, ma semplicemente la quantità di elementi char o wchar_t memorizzati in quella stringa / wstring. Per questo motivo, i wrapper C ++ gtk / glib hanno sviluppato una class Glib::ustring grado di gestire utf-8.

    Se il tuo wchar_t è lungo 32 bit, puoi usare utf-32 come codifica unicode, e puoi memorizzare e gestire stringhe unicode usando una codifica fissa (utf-32 è una lunghezza fissa). Ciò significa che la funzione s.size() del s.size() restituirà la giusta quantità di elementi wchar_t e caratteri logici.

  2. Sì, il char è sempre lungo almeno 8 bit, il che significa che può memorizzare tutti i valori ASCII.
  3. Sì, tutti i principali compilatori lo supportano.

Uso spesso std :: string per mantenere i caratteri utf-8 senza alcun problema. Raccomando caldamente di farlo durante l’interfacciamento con le API che usano anche utf-8 come tipo di stringa nativa.

Per esempio, io uso utf-8 quando interfaccia il mio codice con l’interprete Tcl.

L’avvertenza principale è la lunghezza di std :: string, non è più il numero di caratteri nella stringa.

  1. Quando si desidera memorizzare caratteri “larghi” (Unicode).
  2. Sì: 255 di loro (escluso 0).
  3. Sì.
  4. Ecco un articolo introduttivo: http://www.joelonsoftware.com/articles/Unicode.html

Le applicazioni che non soddisfano solo 256 caratteri diversi hanno le opzioni di utilizzare caratteri ampi (più di 8 bit) o ​​una codifica a lunghezza variabile (una codifica multibyte in terminologia C ++) come UTF-8. I caratteri ampi generalmente richiedono più spazio di una codifica a lunghezza variabile, ma sono più veloci da elaborare. Le applicazioni multi-lingua che elaborano grandi quantità di testo in genere utilizzano caratteri ampi durante l’elaborazione del testo, ma convertirlo in UTF-8 quando lo si archivia su disco.

L’unica differenza tra una string e un wstring è il tipo di dati dei caratteri che memorizzano. Una stringa memorizza i char i cui dimensioni sono garantite da almeno 8 bit, quindi è ansible utilizzare stringhe per l’elaborazione, ad esempio testo ASCII, ISO-8859-15 o UTF-8. Lo standard non dice nulla sul set di caratteri o sulla codifica.

Praticamente ogni compilatore usa un set di caratteri i cui primi 128 caratteri corrispondono ad ASCII. Questo è anche il caso con i compilatori che usano la codifica UTF-8. La cosa importante da sapere quando si usano stringhe in UTF-8 o in qualche altra codifica a lunghezza variabile, è che gli indici e le lunghezze sono misurati in byte, non in caratteri.

Il tipo di dati di un wstring è wchar_t , la cui dimensione non è definita nello standard, tranne per il fatto che deve essere grande almeno quanto un char, solitamente 16 bit o 32 bit. il wstring può essere utilizzato per elaborare il testo nella codifica wide-character definita dall’implementazione. Poiché la codifica non è definita nello standard, non è semplice convertire tra stringhe e stringhe. Non si può nemmeno pensare che le wstrings abbiano una codifica a lunghezza fissa.

Se non hai bisogno di supporto multilingue, potresti usare solo le stringhe normali. D’altra parte, se stai scrivendo un’applicazione grafica, è spesso il caso che l’API supporti solo caratteri ampi. Quindi probabilmente si desidera utilizzare gli stessi caratteri ampi durante l’elaborazione del testo. Tieni presente che UTF-16 è una codifica a lunghezza variabile, ovvero che non puoi assumere length() per restituire il numero di caratteri. Se l’API utilizza una codifica a lunghezza fissa, come UCS-2, l’elaborazione diventa facile. La conversione tra caratteri wide e UTF-8 è difficile da eseguire in un modo portabile, ma poi di nuovo, l’API dell’interfaccia utente probabilmente supporta la conversione.

  1. quando si desidera utilizzare stringhe Unicode e non solo ASCII, utile per l’internazionalizzazione
  2. si, ma non gioca bene con 0
  3. non consapevole di nessuno che non lo faccia
  4. wide character è il modo specifico del compilatore di gestire la rappresentazione a lunghezza fissa di un carattere unicode, per MSVC è un carattere a 2 byte, per gcc mi sembra di capire che è 4 byte. e un +1 per http://www.joelonsoftware.com/articles/Unicode.html

1) Come menzionato da Greg, wstring è utile per l’internazionalizzazione, è allora che rilascerai il tuo prodotto in lingue diverse dall’inglese

4) Controlla questo per carattere ampio http://en.wikipedia.org/wiki/Wide_character

Una buona domanda! Penso che DATA ENCODING (a volte CHARSET coinvolto anche) è un meccanismo di espressione memoria per salvare i dati in file o trasferire dati via rete, quindi rispondo a questa domanda come:

1.Quando dovrei usare std :: wstring su std :: string?

Se la piattaforma di programmazione o la funzione API è a singolo byte e vogliamo elaborare o analizzare alcuni dati unicode, ad es. Letti dal file .REG di Windows o dal stream di 2 byte di rete, dovremmo dichiarare la variabile std :: wstring a easy elaborarli. es: wstring ws = L “中国 a” (memoria 6 ottetti: 0x4E2D 0x56FD 0x0061), possiamo usare ws [0] per ottenere carattere ‘中’ e ws [1] per ottenere carattere ‘国’ e ws [2] per prendi il carattere ‘a’, ecc.

2.Can std :: string tieni premuto l’intero set di caratteri ASCII, inclusi i caratteri speciali?

Sì. Ma nota: ASCII americano, significa che ogni ottetto 0x00 ~ 0xFF rappresenta un carattere, incluso il testo stampabile come “123abc & * _ &” e hai detto uno speciale, per lo più stampalo come un “.” evitare di confondere editori o terminali. E alcuni altri paesi estendono il proprio set di caratteri “ASCII”, ad esempio il cinese, usano 2 ottetti per rappresentare un personaggio.

3.I std: wstring è supportato da tutti i popolari compilatori C ++?

Forse, o soprattutto. Ho usato: VC ++ 6 e GCC 3.3, SÌ

4. Cos’è esattamente un “ampio carattere”?

il carattere ampio indica principalmente l’uso di 2 ottetti o 4 ottetti per contenere i caratteri di tutti i paesi. 2 ottetti UCS2 è un campione rappresentativo, e inoltre ad esempio inglese ‘a’, la sua memoria è 2 ottetto di 0x0061 (vs in ASCII ‘la memoria è 1 ottetto 0x61)

Ci sono alcune ottime risposte qui, ma penso che ci siano un paio di cose che posso aggiungere riguardo a Windows / Visual Studio. Questo è basato sulla mia esperienza con VS2015. Su Linux, in pratica, la risposta è usare lo std::string codificato UTF-8 ovunque. Su Windows / VS diventa più complesso. Ecco perché Windows si aspetta che le stringhe memorizzate utilizzando i char vengano codificati utilizzando la tabella codici locale. Questo è quasi sempre il set di caratteri ASCII seguito da altri 128 caratteri speciali a seconda della posizione. Lasciatemi solo precisare che questo non solo quando si utilizza l’API di Windows, ci sono altri tre punti principali in cui queste stringhe interagiscono con lo standard C ++. Questi sono letterali stringa, output a std::cout usando << e passando un nome file a std::fstream .

Sarò di fronte qui che sono un programmatore, non uno specialista di lingue. Apprezzo che USC2 e UTF-16 non siano gli stessi, ma per i miei scopi sono abbastanza vicini per essere intercambiabili e li uso come tali qui. In realtà non sono sicuro di quale Windows usi, ma generalmente non ho bisogno di saperlo. Ho dichiarato UCS2 in questa risposta, mi dispiace così tanto in anticipo se sconvolgo qualcuno con la mia ignoranza su questo argomento e sono felice di cambiarlo se ho delle cose sbagliate.

Stringhe letterali

Se si immettono valori letterali stringa che contengono solo caratteri che possono essere rappresentati dalla codepage, VS li memorizza nel file con codifica di 1 byte per carattere in base alla codepage. Notare che se si modifica la codepage o si fornisce la propria origine a un altro sviluppatore che utilizza una diversa tabella codici, penso (ma non ho verificato) che il personaggio finirà per essere diverso. Se esegui il tuo codice su un computer utilizzando una diversa tabella codici, non sono sicuro che cambierà anche il personaggio.

If you enter any string literals that cannot be represented by your codepage then VS will ask you to save the file as Unicode. The file will then be encoded as UTF-8. This means that all Non ASCII characters (including those which are on your codepage) will be represented by 2 or more bytes. This means if you give your source to someone else the source will look the same. However, before passing the source to the compiler, VS converts the UTF-8 encoded text to code page encoded text and any characters missing from the code page are replaced with ? .

The only way to guarantee correctly representing a Unicode string literal in VS is to precede the string literal with an L making it a wide string literal. In this case VS will convert the UTF-8 encoded text from the file into UCS2. You then need to pass this string literal into a std::wstring constructor or you need to convert it to utf-8 and put it in a std::string . Or if you want you can use the Windows API functions to encode it using your code page to put it in a std::string , but then you may as well have not used a wide string literal.

std::cout

When outputting to the console using << you can only use std::string , not std::wstring and the text must be encoded using your locale codepage. If you have a std::wstring then you must convert it using one of the Windows API functions and any characters not on your codepage get replaced by ? (maybe you can change the character, I can't remember).

std::fstream filenames

Windows OS uses UCS2/UTF-16 for its filenames so whatever your codepage, you can have files with any Unicode character. But this means that to access or create files with characters not on your codepage you must use std::wstring . Non c'è altro modo. This is a Microsoft specific extension to std::fstream so probably won't compile on other systems. If you use std::string then you can only utilise filenames that only include characters on your codepage.

Your options

If you are just working on Linux then you probably didn't get this far. Just use UTF-8 std::string everywhere.

If you are just working on Windows just use UCS2 std::wstring everywhere. Some purists may say use UTF8 then convert when needed, but why bother with the hassle.

If you are cross platform then it's a mess to be frank. If you try to use UTF-8 everywhere on Windows then you need to be really careful with your string literals and output to the console. You can easily corrupt your strings there. If you use std::wstring everywhere on Linux then you may not have access to the wide version of std::fstream , so you have to do the conversion, but there is no risk of corruption. So personally I think this is a better option. Many would disagree, but I'm not alone - it's the path taken by wxWidgets for example.

Another option could be to typedef unicodestring as std::string on Linux and std::wstring on Windows, and have a macro called UNI() which prefixes L on Windows and nothing on Linux, then the code

 #include  #include  #include  #include  #ifdef _WIN32 typedef std::wstring unicodestring; #define UNI(text) L ## text std::string formatForConsole(const unicodestring &str) { std::string result; //Call WideCharToMultiByte to do the conversion return result; } #else typedef std::string unicodestring; #define UNI(text) text std::string formatForConsole(const unicodestring &str) { return str; } #endif int main() { unicodestring fileName(UNI("fileName")); std::ofstream fout; fout.open(fileName); std::cout << formatForConsole(fileName) << std::endl; return 0; } 

would be fine on either platform I think.

risposte

So To answer your questions

1) If you are programming for Windows, then all the time, if cross platform then maybe all the time, unless you want to deal with possible corruption issues on Windows or write some code with platform specific #ifdefs to work around the differences, if just using Linux then never.

2)Yes. In addition on Linux you can use it for all Unicode too. On Windows you can only use it for all unicode if you choose to manually encode using UTF-8. But the Windows API and standard C++ classs will expect the std::string to be encoded using the locale codepage. This includes all ASCII plus another 128 characters which change depending on the codepage your computer is setup to use.

3)I believe so, but if not then it is just a simple typedef of a 'std::basic_string' using wchar_t instead of char

4)A wide character is a character type which is bigger than the 1 byte standard char type. On Windows it is 2 bytes, on Linux it is 4 bytes.

When should you NOT use wide-characters?

When you’re writing code before the year 1990.

Obviously, I’m being flip, but really, it’s the 21st century now. 127 characters have long since ceased to be sufficient. Yes, you can use UTF8, but why bother with the headaches?