Wie drucke ich Unicode-Zeichen in C++?

Lesezeit: 8 Minuten

Wie drucke ich Unicode Zeichen in C
James Raizew

Ich versuche, ein russisches “ф” (U+0444 Kyrillischer Kleinbuchstabe EF) Zeichen, das einen Dezimalcode erhält 1092. Wie kann ich dieses Zeichen mit C++ ausdrucken? Ich hätte gedacht, dass etwas in der Art des Folgenden funktionieren würde, aber …

int main (){
   wchar_t f="1060";
   cout << f << endl;
}

  • Beachten Sie, dass das Problem zweierlei ist (zumindest wenn es um ein gültiges C++-Programm geht): das Zeichen im Code ausdrücken und es korrekt an übergeben std::cout. (Und selbst wenn diese beiden Schritte korrekt ausgeführt werden, ist es eine ganz andere Sache, das Zeichen in was auch immer korrekt anzuzeigen std::cout ist verbunden mit.)

    – Luc Danton

    18. August 2012 um 4:46 Uhr

  • Beantwortet das deine Frage? Unicode-Codierung für Zeichenfolgenliterale in C++11

    – MJ Rayburn

    24. Juni 2021 um 2:33 Uhr

1646965209 757 Wie drucke ich Unicode Zeichen in C
Namen53

Um den Charakter darzustellen, können Sie Universal Character Names (UCNs) verwenden. Das Zeichen ‘ф’ hat den Unicode-Wert U+0444 und in C++ könnte man es also ‘\u0444’ oder ‘\U00000444’ schreiben. Auch wenn die Quellcodecodierung dieses Zeichen unterstützt, können Sie es einfach wörtlich in Ihren Quellcode schreiben.

// both of these assume that the character can be represented with
// a single char in the execution encoding
char b = '\u0444';
char a="ф"; // this line additionally assumes that the source character encoding supports this character

Das Drucken solcher Zeichen hängt davon ab, worauf Sie drucken. Wenn Sie an einen Unix-Terminalemulator drucken, der Terminalemulator eine Codierung verwendet, die dieses Zeichen unterstützt, und diese Codierung mit der Ausführungscodierung des Compilers übereinstimmt, können Sie Folgendes tun:

#include <iostream>

int main() {
    std::cout << "Hello, ф or \u0444!\n";
}

Dieses Programm nicht erfordern, dass ‘ф’ in einem einzigen Zeichen dargestellt werden kann. Unter OS X und den meisten modernen Linux-Installationen funktioniert dies einwandfrei, da die Quell-, Ausführungs- und Konsolencodierungen alle UTF-8 sind (was alle Unicode-Zeichen unterstützt).

Bei Windows ist es schwieriger und es gibt verschiedene Möglichkeiten mit unterschiedlichen Kompromissen.

Wenn Sie keinen portablen Code benötigen (Sie werden wchar_t verwenden, was auf jeder anderen Plattform wirklich vermieden werden sollte), ist es wahrscheinlich das Beste, den Modus des Ausgabedatei-Handles so einzustellen, dass nur UTF-16-Daten verwendet werden.

#include <iostream>
#include <io.h>
#include <fcntl.h>

int main() {
    _setmode(_fileno(stdout), _O_U16TEXT);
    std::wcout << L"Hello, \u0444!\n";
}

Portabler Code ist schwieriger.

  • ? Ich bin mir ziemlich sicher, dass ‘\u0444’ nicht in ein Zeichen passt, es sei denn, der Compiler hat das Zeichen zu einem Int hochgestuft, aber wenn Sie dieses Verhalten wünschen, sollten Sie ein Int verwenden.

    – Eduard Falk

    4. September 2016 um 20:20 Uhr

  • @EdwardFalk \u0444 passt in 8 Bit char wenn der Ausführungszeichensatz beispielsweise ISO-8859-5 ist. Insbesondere wird es das Byte 0xE4 sein. Beachten Sie, dass ich nicht vorschlage, dass die Verwendung eines solchen Ausführungszeichensatzes eine gute Praxis ist, ich beschreibe einfach, wie C++ funktioniert.

    – Namen53

    5. September 2016 um 3:13 Uhr


  • Ahhh, Sie sagen, der Compiler erkennt \u0444 als Unicode-Zeichen und konvertiert es in den vorherrschenden Zeichensatz, und das Ergebnis passt in ein Byte? Ich wusste nicht, dass es das tun würde.

    – Eduard Falk

    5. September 2016 um 16:03 Uhr

  • Jawohl. Aus diesem Grund verwenden \u unterscheidet sich von der Verwendung \x.

    – Namen53

    6. März 2017 um 2:29 Uhr

  • funktioniert nicht auf meinem Lubuntu 16-Laptop mit Terminator-Terminal und g ++ 5.4.0, die Verwendung eines std :: string hat jedoch funktioniert

    – Austin_Anderson

    15. Oktober 2017 um 18:22 Uhr


Beim Kompilieren mit -std=c++11kann man einfach

  const char *s  = u8"\u0444";
  cout << s << endl;

  • Lassen Sie mich empfehlen Boost.Nowide zum Drucken von UTF-8-Strings auf portable Weise an das Terminal, sodass der obige Code fast unverändert bleibt.

    – Jakow Galka

    30. August 2012 um 10:47 Uhr

  • @ybungalobill, dein Kommentar verdient eine eigene Antwort. Würde es Ihnen etwas ausmachen, eine zu erstellen?

    – Jorge Leitao

    6. Januar 2015 um 13:24 Uhr

  • Nur zu meiner Anmerkung: \uXXXX und \UXXXXXXXX werden genannt universeller Charaktername. Ein Zeichenfolgenliteral des Formulars u8"..." ist UTF-8-String-Literal. Beides ist in der Norm festgelegt.

    – ynn

    27. Dezember 2019 um 11:50 Uhr


Letztendlich ist dies völlig plattformabhängig. Die Unicode-Unterstützung ist in Standard C++ leider sehr schlecht. Für GCC müssen Sie es zu einer schmalen Zeichenfolge machen, da sie UTF-8 verwenden und Windows eine breite Zeichenfolge möchte, und Sie müssen an ausgeben wcout.

// GCC
std::cout << "ф";
// Windoze
wcout << L"ф";

  • IIRC, Unicode-Escapes sind \uXXXX bei dem die XXXX ist für verhexen Ziffern. Leider werden dadurch alle Zeichen nach U+FFFF ausgelassen.

    – Mike DeSimone

    18. August 2012 um 3:39 Uhr

  • @Mike: Wenn Sie an FFFF vorbei wollen, können Sie dies tun, indem Sie selbst ein UTF-16-Ersatzpaar mit zwei Instanzen von generieren \uzumindest unter Windows.

    – Billy ONeal

    18. August 2012 um 3:41 Uhr

  • @BillyONeal Sie verwenden keine Ersatzcodepunkte in C++ (tatsächlich sind Ersatzcodepunkte völlig verboten). Sie verwenden das Format \UXXXXXXXX.

    – Namen53

    18. August 2012 um 3:46 Uhr

  • GCC ist nicht an die Verwendung von UTF-8 gebunden und steht für Windows zur Verfügung. std::wcout ist auch eine Option außerhalb von Windows.

    – Luc Danton

    18. August 2012 um 4:48 Uhr

  • @Marmelade '\u0400' ist ein Literal mit schmalem Zeichen. Davon scheinst du auszugehen \u0400 im Ausführungszeichensatz vorhanden ist. Gemäß N3242 [lex.ccon]/5: “Ein universeller Zeichenname wird in die Kodierung des benannten Zeichens im entsprechenden Ausführungszeichensatz übersetzt. Wenn es keine solche Kodierung gibt, wird der universelle Zeichenname in eine implementierungsdefinierte Kodierung übersetzt.”

    – Neugieriger

    18. August 2012 um 5:01 Uhr

Wie drucke ich Unicode Zeichen in C
Wladasimovic

Wenn Sie Windows verwenden (beachten Sie, dass wir printf() verwenden, nicht cout):

//Save As UTF8 without signature
#include <stdio.h>
#include<windows.h>
int main (){
    SetConsoleOutputCP(65001); 
    printf("ф\n");
}

Nicht Unicode, aber funktioniert – 1251 statt UTF8:

//Save As Windows 1251
#include <iostream>
#include<windows.h>
using namespace std;
int main (){
    SetConsoleOutputCP(1251); 
    cout << "ф" << endl;
}

Dieser Code funktioniert unter Linux (C++11, geany, g++ 7.4.0):

#include <iostream>

using namespace std;


int utf8_to_unicode(string utf8_code);
string unicode_to_utf8(int unicode);


int main()
{
    cout << unicode_to_utf8(36) << '\t';
    cout << unicode_to_utf8(162) << '\t';
    cout << unicode_to_utf8(8364) << '\t';
    cout << unicode_to_utf8(128578) << endl;

    cout << unicode_to_utf8(0x24) << '\t';
    cout << unicode_to_utf8(0xa2) << '\t';
    cout << unicode_to_utf8(0x20ac) << '\t';
    cout << unicode_to_utf8(0x1f642) << endl;

    cout << utf8_to_unicode("$") << '\t';
    cout << utf8_to_unicode("¢") << '\t';
    cout << utf8_to_unicode("€") << '\t';
    cout << utf8_to_unicode("🙂") << endl;

    cout << utf8_to_unicode("\x24") << '\t';
    cout << utf8_to_unicode("\xc2\xa2") << '\t';
    cout << utf8_to_unicode("\xe2\x82\xac") << '\t';
    cout << utf8_to_unicode("\xf0\x9f\x99\x82") << endl;

    return 0;
}


int utf8_to_unicode(string utf8_code)
{
    unsigned utf8_size = utf8_code.length();
    int unicode = 0;

    for (unsigned p=0; p<utf8_size; ++p)
    {
        int bit_count = (p? 6: 8 - utf8_size - (utf8_size == 1? 0: 1)),
            shift = (p < utf8_size - 1? (6*(utf8_size - p - 1)): 0);

        for (int k=0; k<bit_count; ++k)
            unicode += ((utf8_code[p] & (1 << k)) << shift);
    }

    return unicode;
}


string unicode_to_utf8(int unicode)
{
    string s;

    if (unicode>=0 and unicode <= 0x7f)  // 7F(16) = 127(10)
    {
        s = static_cast<char>(unicode);

        return s;
    }
    else if (unicode <= 0x7ff)  // 7FF(16) = 2047(10)
    {
        unsigned char c1 = 192, c2 = 128;

        for (int k=0; k<11; ++k)
        {
            if (k < 6)  c2 |= (unicode % 64) & (1 << k);
            else c1 |= (unicode >> 6) & (1 << (k - 6));
        }

        s = c1;    s += c2;

        return s;
    }
    else if (unicode <= 0xffff)  // FFFF(16) = 65535(10)
    {
        unsigned char c1 = 224, c2 = 128, c3 = 128;

        for (int k=0; k<16; ++k)
        {
            if (k < 6)  c3 |= (unicode % 64) & (1 << k);
            else if (k < 12) c2 |= (unicode >> 6) & (1 << (k - 6));
            else c1 |= (unicode >> 12) & (1 << (k - 12));
        }

        s = c1;    s += c2;    s += c3;

        return s;
    }
    else if (unicode <= 0x1fffff)  // 1FFFFF(16) = 2097151(10)
    {
        unsigned char c1 = 240, c2 = 128, c3 = 128, c4 = 128;

        for (int k=0; k<21; ++k)
        {
            if (k < 6)  c4 |= (unicode % 64) & (1 << k);
            else if (k < 12) c3 |= (unicode >> 6) & (1 << (k - 6));
            else if (k < 18) c2 |= (unicode >> 12) & (1 << (k - 12));
            else c1 |= (unicode >> 18) & (1 << (k - 18));
        }

        s = c1;    s += c2;    s += c3;    s += c4;

        return s;
    }
    else if (unicode <= 0x3ffffff)  // 3FFFFFF(16) = 67108863(10)
    {
        ;  // actually, there are no 5-bytes unicodes
    }
    else if (unicode <= 0x7fffffff)  // 7FFFFFFF(16) = 2147483647(10)
    {
        ;  // actually, there are no 6-bytes unicodes
    }
    else  ;  // incorrect unicode (< 0 or > 2147483647)

    return "";
}

Mehr:

'1060' ist vier Zeichen und wird nicht unter dem Standard kompiliert. Sie sollten das Zeichen einfach als Zahl behandeln, wenn Ihre Breitzeichen 1:1 mit Unicode übereinstimmen (überprüfen Sie Ihre Gebietsschemaeinstellungen).

int main (){
    wchar_t f = 1060;
    wcout << f << endl;
}

1646965210 404 Wie drucke ich Unicode Zeichen in C
MGR

Ich musste die Zeichenfolge in der Benutzeroberfläche anzeigen und in einer XML-Konfigurationsdatei speichern. Das oben angegebene Format ist gut für Strings in C++, ich möchte hinzufügen, dass wir die xml-kompatible Zeichenfolge für das Sonderzeichen haben können, indem wir “\u” durch “&#x” ersetzen und ein “;” hinzufügen. Am Ende.

Zum Beispiel: C++ : “\u0444” –> XML : "&#x0444;"

989600cookie-checkWie drucke ich Unicode-Zeichen in C++?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy