Problem polega na tym, że konsola korzysta z różnych stron kodowych niż reszta systemu. Na przykład zwykle systemy Windows skonfigurowane dla obu Ameryk i Europy Zachodniej używają CP1252, ale konsola w tych regionach używa CP437 lub CP850.
Możesz ustawić stronę kodową wyjścia konsoli tak, aby pasowała do używanego kodowania lub konwertować ciągi tak, aby pasowały do strony kodowej wyjścia konsoli.
Ustaw kodowa wyjście konsoli:
SetConsoleOutputCP(GetACP()); // GetACP() returns the system codepage.
std::cout << "La chaîne qui correspond au code \"TEST_CODE\" n'a pas été trouvée à l'aide locale \"fr\".";
Albo jeden z wielu sposobów do konwersji między kodowań (ten wymaga VS2010 lub nowszej):
#include <codecvt> // for wstring_convert
#include <locale> // for codecvt_byname
#include <iostream>
int main() {
typedef std::codecvt_byname<wchar_t,char,std::mbstate_t> codecvt;
// the following relies on non-standard behavior, codecvt destructors are supposed to be protected and unusable here, but VC++ doesn't complain.
std::wstring_convert<codecvt> cp1252(new codecvt(".1252"));
std::wstring_convert<codecvt> cp850(new codecvt(".850"));
std::cout << cp850.to_bytes(cp1252.from_bytes("...été trouvée à...\n")).c_str();
}
Ten ostatni przykład zakłada, że w rzeczywistości Konwersja pomiędzy 1252 i 850. Prawdopodobnie powinieneś użyć funkcji GetOEMCP(), aby znaleźć rzeczywistą docelową stronę kodową, a źródłowa strona kodowa zależy od tego, czego używasz dla kodu źródłowego, a nie od wyniku GetACP() na maszyna uruchamiająca program.
Należy również zauważyć, że program ten opiera się na czymś, co nie jest gwarantowane przez standard: kodowanie wchar_t jest współużytkowane pomiędzy ustawieniami regionalnymi. Dotyczy to większości platform — zwykle niektóre kodowanie Unicode jest używane do wchar_t we wszystkich lokalizacjach —, ale nie wszystkie.
Idealnie można po prostu użyć UTF-8 oraz dodaje się wszędzie będzie działać dobrze, jak ma to miejsce na innych platformach te dni:
#include <iostream>
int main() {
std::cout << "La chaîne qui correspond au code \"TEST_CODE\" n'a pas été trouvée à l'aide locale \"fr\".\n";
}
Niestety Windows nie obsługuje UTF-8 w ten sposób bez porzucania UTF-16 jako kodowania wchar_t i przyjmowania 4 bajtów wchar_t, lub naruszania wymagań standardu i łamania standardowych programów zgodnych.
Zakładam, że używasz systemu Windows? –
Tak, zmieniam moje pytanie w celu określenia. – jmegaffin
@Boreal: Upewnij się, że konwertujesz ciąg znaków zapisany w pliku na kod Unicode UTF-16 (co ma sens w przypadku kodowania Unicode w aplikacji Windows). Możesz to zrobić czytając ciąg z twojego pliku, a następnie używając 'MultiByteToWideChar()' API (lub pomocnika konwersji ATL 'CA2W'), aby przekonwertować z twojego konkretnego kodowania do UTF-16. Następnie, aby wydrukować ciąg znaków Unicode do konsoli, wystarczy zainicjować konsolę za pomocą '_setmode (_fileno (standardowe), _O_U16TEXT);', a następnie można użyć 'wprintf()' lub 'std :: wcout'. Zobacz moją odpowiedź na dalsze szczegóły i linki. –