ASCII oder UNICODE ?



  • Hi zusammen,
    ich habe eine Frage.
    Ich habe ein c++ Programm geschrieben mit dem ich den Computernamen und andere Informationen eines PCs auslese. Diese Infos werden in einem string gespeichert und dann ich in ein *.txt File geschrieben.

    Nun kann es jedoch sein dass ein PC auf dem dieses Programm ausgeführt wird der Computername zb. Asiatische Zeichen enthält.

    Nun meine Frage:
    Woher weiss ich von welcher Kodierung mein String ist?
    Ich habe gelesen dass ich dies beim Compiler angeben muss, habe aber unter den Project-Eigenschaften nichts gefunden, wo ich so etwas einstellen kann.
    Ich verwende die aktuelle Dev-C++ Entwicklungsumgebung.



  • redbomber schrieb:

    Woher weiss ich von welcher Kodierung mein String ist?

    Entweder per Konvention vereinbaren, in die Datei mit rein schreiben oder (qualifiziert) raten.



  • Die Standardeinstellung sollten heutzutage idr. Unicode sein. Allerdings musst duch auch z.B. std::wstring benutzen um davon gebrauch zu machen. std::string ist ASCII.



  • ok,
    vielen Dank schon einmal.

    Jetzt nochmal eine blöde Frage. Mir ist nicht so ganz klar wo welche Kodierung verwendet wird.

    Also wenn in meinem Programm z.B. der Computername ausgelesen wird, dann erhalte ich die Zeichen in der "originalen" Kodierung (wird wohl in UNICODE sein).

    Nun speichere ich diesen string in z.b. std::string (ASCII). Hier geht dann die "originale" Kodierung verloren? (würde ich std::wstring (UNICODE !?) nehmen, dann nicht)

    Als nächstes schreibe ich den std::string in einem txt-File. In dem Text-File sind somit nur noch ASCII-Zeichen enthalten. Die orginile Kodierung also verloren?
    @SG1: was meinst du dann dass ich die Infos mit in die Datei rein schreiben soll?

    Würde ich einen std::wstring in das txt-file schreiben, dann enthält dieser ASCII zeichen.



  • z.B., dass Du die verwendete Kodierung als erste Zeile in die Datei schreibst.



  • Im Prinzip muss du zwischen dem ASCII und dem Unicode unterscheiden. Unicode hat die doppelte Länge wie ASCII, welches keine chinesischen etc. Zeichen beherbergt (gogle Asciitabelle). Für deine Anwendung musst du darauf achten ausschließlich Methoden und strings zu verwenden die auch width strings/chars (wchar_t, wstring etc.) verwenden. Für das Schreiben von Unicodedateien benutze wfstream!



  • HighLigerBiMBam verbreitet wieder einmal Gerüchte. Wenn du einen Unicode-String in std::string speicherst und dann wieder ausgibst (sei das file oder wfile), geht die Kodierung überhaupt nicht verloren.
    Nur darfst du nicht auf einzelne Zeichen zugreifen die in Unicode den gleichen Wert von ASCII haben, ansonsten bekommst du irgendwelche komischen Werte heraus.

    Wenn die originale Kodierung vom Computernamen allerdings nicht Unicode ist, funktioniert auch wstring nicht. Dann musst du diese von Hand konvertieren (lassen) und ob das Ziel dann ein normaler string oder ein wstring ist spielt hier auch keine Rolle. Und mehr hast du vermutlich auch nicht mit der Zeichenkette vor.

    Ich bin eher für die Konvention, dass alles Unicode ist, anstatt in die erste Zeile die Kodierung hineinzuschreiben.



  • Ob du std::string oder std::wstring verwendest hat überhaupt nichts mit der Kodierung des Strings zu tun! Das sind bloß Container, die nichts vom Inhalt wissen. Wenn ich dich richtig verstanden habe, brauchst du gar nicht zu wissen in welcher Kodierung der String nun vorliegt, denn du möchtest ihn nur so in die Datei schreiben, wie du ihn auch eingelesen hast oder nicht?
    Wenn dein API call dir einen char* gibt, verwendest du halt einen std::string, bei einem wchar_t* einen std::wstring.



  • Unicode hat die doppelte Länge wie ASCII

    Woher hast du den den Mist? Bitte einfach mal nachdenken, ob das was man so schreibt auch stimmt. Anfänger verwirrst du so eher, als dass du ihnen hilfst.



  • Nur darfst du nicht auf einzelne Zeichen zugreifen die in Unicode den gleichen Wert von ASCII haben, ansonsten bekommst du irgendwelche komischen Werte heraus.

    Was wieder für

    typedef basic_string<wchar_t> wstring;
    

    spricht...



  • Ok,
    also mein Aufruf gibt mir ein char*, weswegen ich bisher einen std::string verwendet habe.

    Also wenn ich das jetzt richtig verstanden habe, dann kann ich wie bisher std::string und char verwenden, diese schreibe ich auch wie bisher in eine Text-Datei.

    Somit befindet sich dann in der Text-Datei (egal ob std::string oder std::wstring) die "originale" Kodierung. Es geht also so oder so nichts an Information verloren (Ich mach ja nichts mit dem string, schreibe den nur in eine Datei).

    Wenn ich die Datei dann öffne muss ich in meinem editor nur darauf achten die korrekte Kodierung zu verwenden.



  • ASCIIUnicode schrieb:

    Unicode hat die doppelte Länge wie ASCII

    Woher hast du den den Mist? Bitte einfach mal nachdenken, ob das was man so schreibt auch stimmt. Anfänger verwirrst du so eher, als dass du ihnen hilfst.

    Ascii hat 8 bit ergo 1 Byte Größe...
    Unicode hat 16 bit ergo 2 Byte Größe...



  • HighLigerBiMBam schrieb:

    ASCIIUnicode schrieb:

    Unicode hat die doppelte Länge wie ASCII

    Woher hast du den den Mist? Bitte einfach mal nachdenken, ob das was man so schreibt auch stimmt. Anfänger verwirrst du so eher, als dass du ihnen hilfst.

    Ascii hat 8 bit ergo 1 Byte Größe...
    Unicode hat 16 bit ergo 2 Byte Größe...

    Aber nur unter Windows. Weil Windows als Unicode default UTF-16 Kodierung verwendet. Und deshalb ist unter windows wchar_t 16Bit groß.
    Und es gibt noch andere UNICODE Kodierungsformate wie UTF-8 UND UTF-32.
    Unter Linux Und MAC OSX ist wchar_t 32Bit groß (=UTF-32 Kodierung).



  • Bei mir ist sizeof(wchar_t)=4, also 32 Bit.

    wstring benötigt mehr Speicher als ein normaler string und ich nehme an, dass du in deinem Fall nicht auf einzelne Zeichen zugreifen willst. Zudem gibt dir die Funktion einen char* zurück, es spricht alles eindeutig für string.

    redbomber schrieb:

    Wenn ich die Datei dann öffne muss ich in meinem editor nur darauf achten die korrekte Kodierung zu verwenden.

    Exakt.



  • ASCII-Code ist 7Bit breit und Unicode kann auch 8Bit breit sein (UTF8).



  • Was gerne verwechselt wird ist der Unicode Zeichensatz an sich und dessen jeweilige Kodierung!

    Im Zeichensatz hat jedes Zeichen eine fixe "Nummer", 'A' z.B. 0x41 ("zufällig" wie in ASCII...), andere Zeichen auch höhere Nummern wie 0x6523 oder auch jenseits von 16 Bit (s. Wikipedia "Unicode"). Dieser Zeichensatz ist zunächst einmal abstrakt und nur eine Vereinbarung, welches Zeichen wohin gehört.

    Die Kodierung dagegen bestimmt, wie diese Zeichen im Rechner oder in einer Datei oder über Netz abgelegt werden. UTF-16 braucht immer 2 Bytes und enhält die unteren 65536 Unicode-Zeichen, UTF-8 ist flexibler und hat ein oder mehrere Bytes. Daneben gibt es eben weitere Kodierungen. Da 16 Bit meist ausreichen, wird UTF-16 oft mit "Unicode" verwechselt.

    Als Überblick vielleicht dieser Artikel von Joel: http://www.joelonsoftware.com/articles/Unicode.html

    Zu redbombers Problem: Wenn die Funktion char* zurückgibt, spricht dies doch zumindest gegen UTF-16, denn dieses enthält \0-Bytes. Spätestens da würde ein simples C-String abbrechen?


Log in to reply