Sommario: Cosa devo fare per stampare correttamente una stringa letterale definita nel codice sorgente che è stato memorizzato nella codifica UTF-8 (Windows CP 65001) su una console cmd
utilizzando lo streaming std::cout
?C++ 11 std :: cout << "stringa letterale in UTF-8" alla console cmd di Windows? (Visual Studio 2015)
Motivazione: Vorrei modificare l'eccellente Catch unit-testing framework (come un esperimento) in modo che visualizzerebbe my texts con caratteri accentati. La modifica dovrebbe essere semplice, affidabile e dovrebbe essere anche utile per altre lingue e ambienti di lavoro in modo che possa essere accettata dall'autore come un miglioramento. O se conosci Catch e se c'è qualche soluzione alternativa, potresti postarla?
Dettagli: Cominciamo con la versione ceca del "quick brown fox ..."
#include <iostream>
#include "windows.h"
using namespace std;
int main()
{
cout << "\n-------------------------- default cmd encoding = 852 -------------------\n";
cout << "Příšerně žluťoučký kůň úpěl ďábelské ódy!" << endl;
cout << "\n-------- Windows Central European (1250) set for the cmd console --------\n";
SetConsoleOutputCP(1250);
std::cout << "Příšerně žluťoučký kůň úpěl ďábelské ódy!" << std::endl;
cout << "\n------------- Windows UTF-8 (65001) set for the cmd console -------------\n";
SetConsoleOutputCP(CP_UTF8);
std::cout << "Příšerně žluťoučký kůň úpěl ďábelské ódy!" << std::endl;
}
stampa il seguente (tipo di carattere impostato a Lucida Console):
Il cmd
la codifica predefinita è 852, la codifica Windows predefinita è 1250 e il codice sorgente è stato salvato utilizzando la codifica 65001 (UTF-8 con BOM). Lo SetConsoleOutputCP(1250);
modifica la codifica cmd
(programmaticamente) allo stesso modo di chcp 1250
.
Osservazione: Quando si imposta la codifica 1250, il valore letterale stringa UTF-8 viene stampato correttamente. Credo che possa essere spiegato, ma è davvero strano. C'è qualche decente, umano, modo generale per risolvere il problema?
Update: Il "narrow string literal"
sono memorizzati utilizzando la codifica di Windows-1250 nel mio caso (la codifica di Windows nativo per centrale europea). Sembra essere indipendente dalla codifica del codice sorgente. Il compilatore lo salva nella codifica originale delle finestre . Per questo motivo, il passaggio da cmd
a quella codifica fornisce l'output desiderato. È uggly, ma come posso ottenere le finestre native che codificano in modo programmatico (per passarlo allo SetConsoleOutputCP(cpX)
)? Ciò di cui ho bisogno è una costante valida per la macchina in cui è avvenuta la compilazione. Non dovrebbe essere una codifica nativa per la macchina su cui viene eseguito l'eseguibile.
Il C++ 11 introdotto anche u8"the UTF-8 string literal"
, ma non sembra adattarsi con SetConsoleOutputCP(CP_UTF8);
possibilmente correlate: http://stackoverflow.com/questions/18904081/printing-unicode-characters-c/18906295#18906295 – luk32
@ luk32: Grazie per i riferimenti. Lo guarderò. – pepr
Quando si compila un sorgente UTF-8 in MSVC, converte i valori letterali stringa in codifica nativa se il file inizia con _UTF-8 BOM_. Quando lo rimuovi, la stringa di test dovrebbe essere stampata correttamente nel terzo caso. – Melebius