c ++ - VC ++ compiler/source-charset: utf-8 virker ikke

Indlæg af Hanne Mølgaard Plasc

Problem



Mens jeg eksperimenterer kodeenheder under utf-8 i Visual Studio, har jeg trængt ind i mange faldgruber:



  1. Som standard gemmer VS kildefilen med systemregionel kodning, for mig er det GB2312 (kodeside 936, en kinesisk kodning).


    Løsning: Jeg bruger gem som og gem filen med UTF-8 uden signatur.

  2. Så fandt jeg ud af, at compileren som standard fortolker kildefilen med systemreguleret kodning, som det stadig er GB2312, så jeg fik forvirrende advarsel og syntaksfejl.


    Løsning: Jeg bruger /source-charset:utf-8 til at kompilere, ingen advarsel og fejl. Men størrelsesresultatet er 2 ('知' i GB2312 er kodet med 2 kodeenheder). Men det skal være 3 under utf-8.



'知' Unicode reference
https://unicode-table.com/en/77E5/[12]


(Jeg tror, ​​at man kan bruge et hvilket som helst tegn, der findes i din nuværende systemkodning og utf-8, men med en anden kodeenhedsstørrelse for at lave en lignende test.)


Kode:


#include <iostream>
#include <string>
using namespace std;

    int main(){
        string s = "知";
        cout << s.size() <<endl;
        cout << s << endl;
    }


Desuden bruger Windows-cmd samt powerhell også systemregionel kodning (type chcp i cmd). Så jeg kan ikke udskrive tegn som ə.


Så der er tre ting jeg skal passe på:



  1. Kildefilkodning

  2. Om kompilatoren fortolker kildefilen som forventet

  3. CMD'en kan muligvis ikke vise tegnet, selvom 1. og 2. er tilfredse.



Desuden har jeg en vis forvirring hidrørende fra denne oplevelse:



  1. Hvorfor virker Windows sådan? Kan det bare sætte alt sammen med utf-8? Jeg kopierede den samme fil til Mac, og alt fungerer som forventet. Og det er meget nemt at indstille Macs terminalkodning.

  2. Nogle indlæg, jeg fandt, sagde årsagen er, at nogle kodningsstandarder (som denne GB2312) er oprettet, før utf-8 kommer ud. Og mange af dem er ikke kompatible med utf-8. Så det fortsætter med at bruge til kompatibilitet.


    Men jeg spekulerer på, hvordan uforeneligheden ville opstå? f.eks. Jeg henter NotesPad ++ og installerer alle sprogpakker. Mit system s kodning er GB2312, men jeg kan stadig ændre visningssprog på NotesPad ++ til japansk og det vises godt. Ikke sådan som ????. [13]


Bedste reference


Udtrykket 'source charset' er ikke tilfældigt her. C ++ -standarden differentierer eksplicit mellem (grundlæggende) kilde tegn sæt (96 almindelige tegn, alle findes i almindelig ASCII) og udførsels tegn sæt.


Siden du brugte UTF-8 som kildesignal, er kortlagt til u77E5.


På kørselstidspunktet bruger du imidlertid eksekverings tegnsæt . VC ++ /source-charset indstillingen påvirker ikke VC ++ 's eksekverings tegnsæt; for det er der en /execution-charset


Men som Matthew Italia allerede noterer, er VC ++ runtime kendt for at være mere end en smule flaky, når det kommer til UTF-8 I/O. std::string.size skal arbejde, men std::cout måske ikke.