Erstellen einer Textdatei in Unicode

Hallo,

Ich hab folgendes Problem:

Ich will mit einem C-Programm eine Textdatei anlegen die in Unicode kodiert sein soll. In diese Datei werden anschließend Daten geschrieben.
ich verwende fopen und fwprintf. Die Strings werden erfolgreich abgelegt. Das Problem ist nur es ist in der Kodierung ASCII und nicht Unicode.
soweit ich weiß steht wchar_t für 16 bit und unicode. da fwprintf wchar_t verlangt und in eine Datei schreibt, bin ich davon ausgegangen dass die Daten, die in die Datei geschrieben werden, in unicode sind. Dies ist aber nicht der Fall.

hier schrittweise was ich durchführe:

setlocale(LC_ALL, „de_DE.UTF-8“);

FILE *bu_file;

bu_file = fopen(file_name, „w+“); // file_name = vollständiger Pfad

fwprintf(bu_file,L"ABC");

fclose(bu_file);

Wie kann ich es erreichen das mittels ein C-Programms eine Textdatei in unicode erstellt wird??

Hallo,

Ich will mit einem C-Programm eine Textdatei anlegen die in
Unicode kodiert sein soll.

Unicode ist keine Kodierung. Du könntest UTF-8 oder UTF-16 oder UTF-7 oder irgend etwas in diese Richtung nehmen, aber du musst dich erst mal für eines davon entscheiden.

In diese Datei werden anschließend
Daten geschrieben.
ich verwende fopen und fwprintf. Die Strings werden
erfolgreich abgelegt.

Wo werden die Strings erfolgreich abgelegt? Wie stellst du das fest?

Das Problem ist nur es ist in der
Kodierung ASCII und nicht Unicode.

wie gesagt: Unicode ist keine Kodierung.

soweit ich weiß steht wchar_t für 16 bit und unicode.

wchar_t steht für 16 bit, aber das kannst du beliebige Daten reinschreiben - es findet auch keine Konvertierungsmagie statt.

da
fwprintf wchar_t verlangt und in eine Datei schreibt, bin ich
davon ausgegangen dass die Daten, die in die Datei geschrieben
werden, in unicode sind. Dies ist aber nicht der Fall.

Richtig.
Wie liegen denn die Daten vor? Sind die in einer bestimmten Kodierung, die du umwandeln willst, oder hast du eine Liste von Codepoints? Wo kommen die Daten her?

Grüße,
Moritz

danke für die antwort :smile:

Unicode ist keine Kodierung. Du könntest UTF-8 oder UTF-16
oder UTF-7 oder irgend etwas in diese Richtung nehmen, aber du
musst dich erst mal für eines davon entscheiden.

Die Kodierung soll UTF-8 sein.

Wo werden die Strings erfolgreich abgelegt? Wie stellst du das
fest?

In einer Text-Datei! (Die im moment in ASCII ist, aber UTF-8 sein soll)

in meinen Programm hole ich mir die Daten (in form eines Strings) aus einer Datenbank. Diese liegen in ASCII vor. Mit mbstowcs will ich den string in wchar wandeln. Ist die frage ob das schon UTF-8 ist?
und wenn nicht wie kann ich daraus UTF-8 machen.

Ich hatte es auch mal einfach so probiert:

fwprintf(bu_file,L"ABC");

Das L gibt ja an das es wcahr ist. ist das auch utf-8??

Hallo,

Unicode ist keine Kodierung. Du könntest UTF-8 oder UTF-16
oder UTF-7 oder irgend etwas in diese Richtung nehmen, aber du
musst dich erst mal für eines davon entscheiden.

Die Kodierung soll UTF-8 sein.

Gut.

Wo werden die Strings erfolgreich abgelegt? Wie stellst du das
fest?

In einer Text-Datei! (Die im moment in ASCII ist, aber UTF-8
sein soll)

Dann passt ja alles. ASCII definiert nur die ersten 128 (oder 127?) Zeichen, und alle ASCII-Zeichen sind identisich mit ihrer UTF-8-Darstellung. ASCII enthält auch keine Umlaute.

in meinen Programm hole ich mir die Daten (in form eines
Strings) aus einer Datenbank. Diese liegen in ASCII vor. Mit
mbstowcs will ich den string in wchar wandeln. Ist die frage
ob das schon UTF-8 ist?

Nein. Aus der Manpage:

mbstowcs - convert a multibyte string to a wide character string

ASCII-String sind kein multibyte string.

Das übliche Format bei „high level“-Programmiersprachen (wie z.B. Perl) ist folgendes:
Alle eingehenden Daten werden in ein internes Format umgewandelt, darin verarbeitet, um am Ende als UTF-8 ausgegeben.

Dabei ist es praktisch, das interne Format so zu wählen, dass man pro Codepoint nur eine Speicheradresse hat. Wenn man nur in der „Basic Multilingual Plane“ arbeitet, reichen dafür 16 Bit, d.h. wchars bieten sich an.

Ich vermute, dass mbstowcs solche Strings erzeugt, aber das ist kein UTF-8. Um das zu erreichen, musst du nochmal extra konverteiren.

Lies dir mal in Ruhe http://de.wikipedia.org/wiki/Unicode und http://de.wikipedia.org/wiki/UTF-8 durch, vielleicht wird dir dann das ganze etwas klarer. Sehr geholfen hat mir auch das hier:
http://www.joelonsoftware.com/articles/Unicode.html
(„The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)“).

Grüße,
Moritz

Ich sehe bei dir einige Unklarheiten.

Unicode versucht jedem Zeichen auf diesem Planeten eine Nummer
zuzuordenen. Will man diese Zeichen in eine Datei schreiben
(eine Datei ist ein Folge von bytes, das hat erstmal nichts
mit „Text“ zu tun), dann muss man diese Unicodezeichen irgendwie
kodieren.

Es gibt Kodierungen, die koennen nur einen bestimmen Teil aller
Unicode Zeichen darstellen, andere Kodierungen schaffen das vollsändige Unicode. Hier einige Beispiele:

ASCII (7-bit) unterstützt nur Unicodezeichen 0-127. Und die werden
auch genau 1-zu-1 so in die Datei geschrieben, sprich, Unicodezeichen
51 wird zum Beispiel als byte mit Wert 51 abgespeichert.

ISO 8859-1 (aka Latin1, 8-bit) kennt zusätzlich zu ASCII noch Umlaute
und so Zeugs für uns Europäer.

wchar_t nutzt 16bit=2byte pro Zeichen, das erlaubt schon eine ganze
Menge an Unicodezeichen, reicht aber nicht um das vollständige Unicode
abzubilden.

UTF-8 hingegen schafft alle Unicodezeichen, weil hier mit variabler
byte-Länge gearbeitet wird: für die ASCII-Zeichen wird 1 byte
verwendet, für andere Zeichen werden 2bytes verwendet, usw…
(nebenbei bemerkt: „ASCII-Zeichen“ ist eigentlich falsch ausgedrückt,
korrekt muss es Unicodezeichen 0-127 heissen)


Nun zu deiner Aufgabenstellung.
Wenn du einfach nur ASCII text bekommst und du das also ‚unicode‘ speichern willst, benutzte einfach fprintf() und alles passt.
Als Ergebnis bekommst du eine Datei, die nur bytes 0-127 enthält.
Das ist valides, lesbares ASCII, und gleichzeitig valides, lesbares
UTF-8 (ASCII und UTF-8 stellen bereich 0-127 identisch dar).

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Danke nochmal,
ich habe die links mir mal angeschaut und mir ist einiges klarer geworden.

Ich vermute, dass mbstowcs solche Strings erzeugt, aber das
ist kein UTF-8. Um das zu erreichen, musst du nochmal
extra konverteiren.

Wie kann ich aber nun meinen String in utf-8 konvertieren? Gibt es dafür eine Funktion oder muss ich mir einen Algorithmus selbst ausdenken?

Mein Ziel ist es ja das ich am Ende ein Text-Datei in UTF-8 erhalte. Ich will damit erreichen das wenn umlaute in der Dateienhalten sind, dass diese auch auf anderen Betriebssystemen angezeit werden.

Hallo,

Wie kann ich aber nun meinen String in utf-8 konvertieren?
Gibt es dafür eine Funktion oder muss ich mir einen
Algorithmus selbst ausdenken?

Ich kenne mich mit den entsprechenden C-Funktionen nicht mehr aus, weil ich jegliche Textverarbeitung inzwischen mit Perl mache. Aber auf meinem System gibt es z.B. FcUcs4ToUtf8 (in fontconfig.h - muss mich das jetzt misstrauisch machen?), aber ich vermute es gibt elegantere Varianten.

Bevor du so etwas von Hand implementierst, solltest du nach Bibliotheken suchen, die das für dich machen.

Mein Ziel ist es ja das ich am Ende ein Text-Datei in UTF-8
erhalte. Ich will damit erreichen das wenn umlaute in der
Dateienhalten sind, dass diese auch auf anderen
Betriebssystemen angezeit werden.

Dazu braucht man noch nicht zwangsläufig UTF-8. Wenn du z.B. alles in latin1 kodierst, dann werden fast alle Systeme damit umgehen können - vorausgesetzt du bringst ihnen bei, dass die Eingabe latin1 kodiert ist.

HTH,
Moritz