Unicode- Zeichen ausgeben



  • Hallo leute,

    habe eine Frage... Und zwar wenn ich an meinen Socket UNICODE zeichen erhalte kann ich dir bei der Konsole nicht ausgeben bzw. ich kriege für jeden UNICODE zeichen irgendwas seltsames...

    mein code:

    void TCP::empfangen(){
    
    char buf [4096];
    int bytes;
    
    bytes = recv (s,buf,sizeof(buf)-1,0);
    
    if (bytes==-1){
     perror ("Error");
    }
    
    buf [bytes] = "\0";
    printf("Received: \%s\"\n", buf);
    }
    

    Habt ihr ne idee wie ich die Zeichenkette komplett richtig darstellen kann ?

    Vielen Dank im Vorraus für eure anregungen

    Gruß



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x) in das Forum C (C89 und C99) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Gast Jan schrieb:

    wenn ich an meinen Socket UNICODE zeichen erhalte kann ich dir bei der Konsole nicht ausgeben bzw. ich kriege für jeden UNICODE zeichen irgendwas seltsames...

    Dann sind deine Daten anders codiert, als deine Konsole erwartet. Es gibt ja viele Möglichkeiten, Unicode zu codieren. Welche wird von deinen Daten benutzt, und welche von deiner Konsole?

    @Forumbot: printf-Kniesehnenreflex? C wird sich mit dem Doppeldoppelpunkt schwer tun.



  • Diese Vermutung hatte ich auch mit der Kodierung.

    Also so wie ich das verstehe kommen meine Daten in Unicode an und die Konsole erwartet ASCII, beantwortet das deine Frage ?



  • Gast Jan schrieb:

    Also so wie ich das verstehe kommen meine Daten in Unicode an und die Konsole erwartet ASCII, beantwortet das deine Frage ?

    Nein. "Unicode" ist zu ungenau. Es gibt viele Unicode-Codierungen, z.B. UTF-8, UCS-2 usw.

    Was die Konsole angeht: Welches Betriebssystem benutzt du? Linux verwendet üblicherweise UTF-8. Bei Windows müsstest du zunächst darauf achten, dass überhaupt eine Schriftart benutzt wird, die die benötigten Zeichen enthält.


  • Mod

    MFK schrieb:

    @Forumbot: printf-Kniesehnenreflex? C wird sich mit dem Doppeldoppelpunkt schwer tun.

    Ähh, ups. Haste Recht. Ich lass es dennoch hier, weil es in erster Linie eine printf-Frage ist. Mit wcout und C++-Locales wird der Threadersteller vermutlich nicht weiterkommen.



  • SeppJ schrieb:

    Mit wcout und C++-Locales wird der Threadersteller vermutlich nicht weiterkommen.

    Auch wieder wahr. Vielleicht stellt sich ja gleich heraus, dass die Codierung der Windows-Eingabeaufforderung umgestellt werden muss, dann kann das nach WinAPI.



  • Achso verstehe...

    Es läuft unter Ubuntu... Desweiteren werden die Daten als UTF-8 gesendet bzw. soll ich empfangen!



  • Da der ursprüngliche Code etwas C++ enthält...ich benutze Folgendes in einem kleinen Programm:

    #include <string>
    #include <vector>
    
    #include <iconv.h>
    
    class iconverter {
    public:
      iconverter(std::string const &to,
                 std::string const &from)
        : converter_(iconv_open(to.c_str(), from.c_str())) { }
    
      ~iconverter() {
        iconv_close(converter_);
      }
    
      std::string operator()(std::string const &in) {
        std::vector<char> outbuf(in.size() * 4);
        std::vector<char> inbuf(in.begin(), in.end());
    
        std::size_t  inchars =  inbuf.size();
        std::size_t outchars = outbuf.size();
    
        char *inptr  = &inbuf[0];
        char *outptr = &outbuf[0];
    
        std::size_t converted_chars = iconv(converter_,
                                            & inptr, & inchars,
                                            &outptr, &outchars);
        iconv(converter_, 0, 0, 0, 0);
    
        if(converted_chars == static_cast<std::size_t>(-1)) {
          return in;
        }
    
        return std::string(&outbuf[0], outptr);
      }
    
    private:
      iconv_t converter_;
    };
    
    // ...
    iconverter convert("iso8859-1//TRANSLIT", "UTF-8");
    
    std::cout << convert(buf);
    

    Es ist nicht sonderlich optimiert, aber auf POSIX-konformen Systemen tut es, was es soll.

    Unter Windows wäre es wahrscheinlich am sinnvollsten, den Kram mit MultiByteToWideChar umzuwandeln und std::wcout zu benutzen.



  • Gast Jan schrieb:

    Es läuft unter Ubuntu... Desweiteren werden die Daten als UTF-8 gesendet bzw. soll ich empfangen!

    Das sollte eigentlich von allein gehen.

    Was empfängst du denn genau (Bytes) und was wird ausgegeben? Gib mal ein Beispiel.



  • @seldon: Danke, es müsste aber bestimmt eine andere möglichkeit von c selbst geben in der Bibliothek.

    @MFK: sende : .\c:\\bliebla\\user
    empfange: ##gnakc32

    Dabei stehen die Route zeichen für irgendein Ascii zeichen was nicht dargestellt werden kann.



  • Welche Bytes empfängst du genau?

    Und bist du wirklich ganz sicher, dass du als UTF-8 sendest? Das sieht nach einem Windows-Pfad aus, und unter Windows ist UTF-8 eher unüblich, da würde ich eher UCS-2 vermuten.



  • Wo sehe ich denn welche bytes ich sende... laut Wireshark ist es genua das was ich sende!

    Deseweiteren war es nur ein Beispiel, habe natürlich kein Windows pfad erhalten 🙂



  • Gast Jan schrieb:

    Wo sehe ich denn welche bytes ich sende... laut Wireshark ist es genua das was ich sende!

    Wireshark zeigt dir die Daten, die du dir ausgedacht hast? Oder was jetzt?

    Gast Jan schrieb:

    Deseweiteren war es nur ein Beispiel, habe natürlich kein Windows pfad erhalten 🙂

    An irgendwelchen ausgedachten Daten kann ich aber nicht prüfen, ob die Codierung so ist, wie du sie erwartest.



  • Gast Jan schrieb:

    void TCP::empfangen(){
    
    char buf [4096];
    int bytes;
    
    bytes = recv (s,buf,sizeof(buf)-1,0);
    
    if (bytes==-1){
     perror ("Error");
    }
    
    buf [bytes] = "\0";
    printf("Received: \%s\"\n", buf);
    }
    

    Habt ihr ne idee wie ich die Zeichenkette komplett richtig darstellen kann ?

    Schon mal die ANSI Funktionen probiert?

    #include <wchar.h>
    void TCP::empfangen(){
    
    char buf [4096];
    int bytes;
    
    bytes = recv (s,buf,sizeof(buf)-1,0);
    
    if (bytes==-1){
     perror ("Error");
    }
    
    buf [bytes] = 0;
    wprintf(L"Received: \%s\"\n", (wchar_t*)buf);
    }
    


  • wprintf arbeitet nicht mit UTF-8, sondern üblicherweise mit UCS-2 oder UCS-4.



  • unter linux tut es für die utf-8 ausgabe ein gewöhnliches printf, wenn es eine der neueren linux-versionen ist.



  • oink schrieb:

    unter linux tut es für die utf-8 ausgabe ein gewöhnliches printf, wenn es eine der neueren linux-versionen ist.

    Willst du das nicht den Unix-Leuten erzählen?
    🙂


Log in to reply