c ++ - wcout output ikke som ønsket

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har forsøgt at skrive en c + + ansøgning til et projekt, og jeg løb ind i dette problem. Grundlæggende:


class OBSClass
{
public:
    wstring ClassName;
    uint8\_t Credit;
    uint8\_t Level;

    OBSClass() : ClassName(), Credit(), Level() {}
    OBSClass(wstring name, uint8\_t credit, uint8\_t hyear)
    : ClassName(name), Credit(credit), Level(hyear)
    {}
};


I en anden fil:


vector<OBSClass> AllClasses;
...
AllClasses.push\_back(OBSClass(L"Bilişim Sistemleri Mühendisliğine Giriş", 3, 1));
AllClasses.push\_back(OBSClass(L"İş Sağlığı ve Güvenliği", 3, 1));
AllClasses.push\_back(OBSClass(L"Türk Dili 1", 2, 1));
... (rest omitted, some of entries have non-ASCII characters like 'ş' and 'İ')


Jeg har en funktion, der stort set outputs alt i AllClasses, problemet er wcout output ikke som ønsket.


void PrintClasses()
{
    for (size\_t i = 0; i < AllClasses.size(); i++)
    {
        wcout << "Class: " << AllClasses[i].ClassName << "
";
    }
}


Output er 'Klasse: Bili' og intet andet. Programmet forsøger ikke engang at sende andre poster og bare hænger. Jeg er på Windows ved hjælp af G ++ 6.3.0. Og jeg bruger ikke Windows 'cmd, jeg bruger bash fra mingw, så kodning vil ikke være problem (eller er det ikke?). Nogle forslag?


Rediger: Også kildekoden kodning er ikke et problem, bare tjekket det er UTF8, standard af VSCode


Rediger: Også lige tjekket for at finde ud af om problemet er med string-bogstaver.


wstring test;
wcin >> test;
wcout << test;


Indtastet nogle ikke-ASCII-tegn som 'ö' og 'þ', det virker perfekt. Hvad er problemet med brede streng-bogstaver?


Rediger: Her går du


#include <iostream>
#include <string>
#include <vector>

using namespace std;

vector<wstring> testvec;

int main()
{
    testvec.push\_back(L"Bilişim Sistemleri Mühendisliğine Giriş");
    testvec.push\_back(L"ıiÖöUuÜü");
    testvec.push\_back(L"☺☻♥♦♣♠•◘○");
    for (size\_t i = 0; i < testvec.size(); i++)
        wcout << testvec[i] << "
";
    return 0;
}


Kompilér med G ++:
g ++ file.cc -O3


Denne kode udsender kun 'Bili'. Det skal være noget med g ++ screwing up binær kodning (?), Da indtastning af værdier med wcin, så udgives dem med wcout ikke noget problem.

Bedste reference


Følgende kode virker for mig ved at bruge MinGW-w64 7.3.0 i både MSYS2 Bash og Windows CMD; og med kilden kodet som UTF-8:


#include <iostream>
#include <locale>
#include <string>
#include <codecvt>

int main()
{
    std::ios\_base::sync\_with\_stdio(false);

    std::locale utf8( std::locale(), new std::codecvt\_utf8<wchar\_t> );
    std::wcout.imbue(utf8);

    std::wstring w(L"Bilişim Sistemleri Mühendisliğine Giriş");
    std::wcout << w << '
';
}


Forklaring:



  • Windows-konsollen understøtter ikke nogen form for 16-bit output, det er kun ANSI og en delvis UTF-8-understøttelse. Så du skal konfigurere wcout for at konvertere output til UTF-8. (Spørg mig ikke hvorfor dette ikke er standardadfærden ...)

  • imbue med en codecvt\_utf8 opnår dette; men du skal også deaktivere sync\_with\_stdio ellers bruger streamen ikke ens facetten, det forsvinder bare til stdout, som har et lignende problem.



For at skrive til andre filer fandt jeg, at den samme teknik virker til at skrive UTF-8. For at skrive en UTF-16-fil skal du indgravere wofstream med en UTF-16-facet, se eksempel her, og skriv en BOM manuelt. [20]





Kommentar: Mange mennesker undgår helt at forsøge at bruge brede iostreams på grund af disse problemer.


Du kan skrive en UTF-8-fil ved hjælp af en smal strøm; og have funktionskald i din kode for at konvertere wstring til UTF-8, hvis du bruger wstring internt; du kan selvfølgelig bruge UTF-8 internt.


Selvfølgelig kan du også skrive en UTF-16-fil ved hjælp af en smal strøm, bare ikke med operator<< fra en wstring.