Shamharoth Geschrieben 12. April 2010 Teilen Geschrieben 12. April 2010 hallo zusammen. ich mal wieder und mein Problem bezüglich verschiedenen charsets. vorinformation: ich arbeite C++ unter linux mein problem: ich möchte einen eingehenden string von z.b. iso-8859-1 in utf-8 konvertieren (geht über iconv). den multibyte-string, den ich bekomme, soll nun in einen widechar gespeichert werden (sollte mit mbstowcs gehen). leider geht dies nicht (ich wollt einfach den satz mit einfügen X) ). wenn der string ein umlaut enthält bekomme ich bei mbstowcs() ein -1 (Fehler) zurück. Mein testlauf: Eingangsstring: abö (hab ich über strlin in char-array gespeichert) Konvertierter String (ISO-8859-2 -> UTF-8): abö (hier sieht man ja wurde in ein mb-string konvertiert) wenn ich jetzt z.b. die länge der kette ermitteln will int mbslen(char *strptr) { int i = 0; int charlen; mblen(NULL, 0); while (charlen = mblen(strptr, MB_LEN_MAX)) { if (charlen < 0) { return -1; } strptr += charlen; i++; } return i; } bekomme ich n -1 an der 3. stelle. die minifunktion wird ja sozusagen benötigt, da ich ja in mbstowcs(dest,src,len) ja zum schluss die länge des zielstrings angeben muss (sollte ja eigentlich genau lang wie mein übergabestring sein). irgend etwas mach ich falsch, aber was ??? wäre super wenn ihr mir helfen könntet (bin schon seit 3 tagen am rätseln) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 12. April 2010 Teilen Geschrieben 12. April 2010 ich möchte einen eingehenden string von z.b. iso-8859-1 in utf-8 konvertieren (geht über iconv). den multibyte-string, den ich bekomme, soll nun in einen widechar gespeichert werden (sollte mit mbstowcs gehen).Warum der Umweg über UTF-8? Warum nicht gleich von iso-8859-1 in Wide Character? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 12. April 2010 Autor Teilen Geschrieben 12. April 2010 weil der string unabhängig von der eingangskonvertierung bearbeitet werden soll. jedoch wenn die verschiedenen Charsetts sofort richtig bei der konv. in wide char geändert werden brauch ich wirklich keins mehr .... muss ich mal überprüfen. ... frag is dann nur noch wie es z.b. mit ländern wie tschechen mit ihren 20 zusatzzeichen is ..... bzw. mit den deutschen umlauten ..... wie gesagt .... muss probieren Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 12. April 2010 Teilen Geschrieben 12. April 2010 iconv kann auch direkt in Wide-Character-Unicode konvertieren (UTF-32 bzw. UCS-4) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 12. April 2010 Autor Teilen Geschrieben 12. April 2010 problem dabei is doch noch, dass iconv char als rückgabewert hat. ... wie ist dann die konvertierung zum wchar_t? müsste doch trotzdem über mbstowcs gehen (könnte sein, dass ich da ne funktion irgendwie nich in verbindung bring?) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 12. April 2010 Teilen Geschrieben 12. April 2010 problem dabei is doch noch, dass iconv char als rückgabewert hat.Der Rückgabewert ist size_t. Ich nehme an, du meinst den outbuf-Parameter. Das ist nur ein Puffer, der Typ sagt da nicht viel aus. Du kannst ein wchar_t-Array benutzen und das beim Aufruf auf char* casten. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 12. April 2010 Autor Teilen Geschrieben 12. April 2010 aah verstehe *kleines lämpchen im kopf angeht* wenn es durch einfaches casten geht, müsst ich es gleich mal ausprobieren bezüglich des direkten convertieren über mbstowcs hab ich es mal probiert hat nicht funktioniert. (gleiches prob als würd ich es über UTF-8 zuerst versuchen.) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 12. April 2010 Autor Teilen Geschrieben 12. April 2010 (bearbeitet) hmmm missd ..... also ich hab jetz das über UTF32 versuchd ... *Input = toWCHAR(*Input, (const char*)Charset); wcscpy(tmpwchr,(wchar_t*)(*Input)); wsInput = tmpwchr; std::wcout << L"X" << wsInput << L"X"; leider bekomm ich bei Sonderzeichen noch ne fehlerhafte ausgaben .... wäre mein Input "abc" stände "XabcX" auf dem Bildschirm. steht jedoch "abcä" im Input, steht "Xabc??" am Monitor. bei "abcü" steht sogar "Xabc? 1/4 X". zur info bezüglich meines codes: toWCHAR() bekmmt input übergeben un aktuellen charset. die funktion ruft wiederum eine firmeninterne funktion auf, welche die daten verarbeitet und iconv ausführt. darum hat die firmeninterne funktion (wird iconvert genant) statt size_t a char * als rückgabewert (darum auch vorhin das mit rückgabewert ^^). rest müsste verständlich sein ... wsInput is vom typ wstring (habs damit auch probierd darum steht es mit drinnen) und tmpwchr is vom typ wchar_t. edit: ach un nebenbei danke für deine mühe scho klasse dass du hier im forum zeit verbringsd um andren zu helfen ^^ (hab vorhin beim thema suchen ein thread entdeckt, bei dem ein andrer sehr schroff wurde, obwohl du sehr sachlich geblieben bisd ) Bearbeitet 12. April 2010 von Shamharoth Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 12. April 2010 Teilen Geschrieben 12. April 2010 Funktioniert denn std::wcout << L"abcä"; bei dir? Meine Konsole hat anscheinend Schwierigkeiten mit wcout. Wenn ich die Daten in eine Textdatei schreibe und mir den Hexdump ansehe, ist alles OK, es ist sogar ein BOM drin. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 13. April 2010 Autor Teilen Geschrieben 13. April 2010 ich hab mal das wcout probiert und bei mir kommt "abc?" raus. jedoch wenn ich das "abcö" in ein char * über "cin >> " mach, wird das char richtig ausgegeben gleich nach dem einlesen (also steht "abcö" am bildschirm). das gleiche wenn ich es hardcoded ausgebe ... (speicherung wird ja in n char* gemachd). vielleichd is ja der string dadurch schon UTF-8? ..... kann ich mir jedoch nichd vorstellen. bezüglich iconv bin ich zufüllig auf das beispiel gekommen: iconv Examples - The GNU C Library <- hier wird aus ner datei mit x-beliebiges charset sofort in wchar_t umgewandelt .... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 13. April 2010 Teilen Geschrieben 13. April 2010 ich hab mal das wcout probiert und bei mir kommt "abc?" raus.Deine Konsole kann also auch nicht so einfach Wide-Character-Strings ausgeben. Die Konsole ist damit nicht geeignet für die Erfolgsprüfung. Wie gesagt, wenn ich den von iconv umgewandelten Text in eine Datei schreibe, ist der in Ordnung. Was soll denn hinterher in deinem Programm mit den Wide-Character-Strings passieren? jedoch wenn ich das "abcö" in ein char * über "cin >> " mach, wird das char richtig ausgegeben gleich nach dem einlesen (also steht "abcö" am bildschirm).Logisch, du liest in UTF-8 ein und gibst in UTF-8 wieder aus. das gleiche wenn ich es hardcoded ausgebe ... (speicherung wird ja in n char* gemachd). vielleichd is ja der string dadurch schon UTF-8? .....Na sicher. Dein Quellcodeeditor benutzt mit sehr hoher Wahrscheinlichkeit auch UTF-8. Du kannst dir ja mal sizeof("ä") ausgeben lassen, sollte 3 sein (eine UTF-8-Sequenz aus zwei Bytes und ein Nullterminator). Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 13. April 2010 Autor Teilen Geschrieben 13. April 2010 (bearbeitet) mein programm soll verschiedene typen prüfen (z.b. isd input numerisch oder alphanumerisch, das einfachste mal als beispiel). damit dann charset unabhängig ist und auch z.b. osteuropäische zeichensätze benutzt werden kann, sollte intern in UTF8 (bzw. eigentlich is es ja UTF32) laufen. k also bedeutet es, dass intern wennman "abcö" schreibt für "ö" n multibyte automatisch bekommt. ich hab jetzt n kleines prüfprogramm gemachd zum testen int main(void){ char cstr[40] = "abcö"; char *pcstr = cstr; wchar_t *pwcstr = NULL; FILE *ffile; std::cin >> cstr; std::cout << sizeof(cstr) << " / " << strlen(cstr) << " / " << mblen(cstr,500) << std::endl; pcstr = toWCHAR(pcstr,"ISO-8859-1"); std::cout << pcstr << std::endl; pwcstr = (wchar_t *)pcstr; std::wcout << pwcstr << wcslen(pwcstr) << std::endl; ffile = fopen("/.../test.txt","w"); fwrite(pwcstr,4,wcslen(pwcstr),ffile); fclose(ffile); return 0; } char * toWCHAR(char * sString, const char * from) { const char * to = "WCHAR_T"; return iconvert(sString, from, to); } char * fromWCHAR(char * sString, const char * to) { const char * from = "WCHAR_T"; return iconvert(sString, from, to); } hierbei bekomme ich bei "abcö" aufn bildschirm: 40 / 5 / 1 a abcö5 und in die datei: a b c d � � sollte nicht dann wcslen 4 zurückgeben? weil bei "ööö" bekomme ich "6" zurück edit: ok wenn ich mein from - charset auf UTF8 ändere kommt schon mal richtige länge raus ... abc�4 Bearbeitet 13. April 2010 von Shamharoth Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 13. April 2010 Autor Teilen Geschrieben 13. April 2010 misd ich kanns nicht mehr editieren :/ darum n doppelpost von mir: ich hab etwas in ner manpage gefunden: f the format string contains non-ASCII wide characters, the program will only work correctly if the LC_CTYPE category of the current locale at run time is the same as the LC_CTYPE category of the current locale at compile time. This is because the wchar_t representation is platform and locale dependent. (The GNU libc represents wide characters using their Unicode (ISO-10646) code point, but other platforms don't do this. Also, the use of C99 universal character names of the form \unnnn does not solve this problem.) Therefore, in internationalized programs, the format string should consist of ASCII wide characters only, or should be constructed at run time in an internationalized way (e.g. using gettext() or iconv(), followed by mbstowcs()). so könnte evtl ein problem geben bei der rückkonvertierung geben (hab auch n fehler, da wennich dann fromWCHAR() mach, hüpfd er in ne endlosschleife. wenn ich dann den widechar von wchar_t in a multibyte char änder, fliegt er auch beim sonderzeichen raus. hier is aber das problem: es ist ja ne bibliothek und soll ja von verschiedenen programmen (egal des locals) genutzt werden. jetz die große frage: ist es möglich den local zu belassen? weil ansonsten müsste ja in derbibliothek das geändert werden, wodurch der rest des programmes beeinträchtigt werden könnte. die ganze problemstellung bereitet mir kopfzerbrechen ^^ Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 13. April 2010 Teilen Geschrieben 13. April 2010 Nimm doch einfach nicht "wchar_t", sondern eine vom aktuellen Locale unabhängige Codierung, wie beispielsweise UTF-32. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 13. April 2010 Autor Teilen Geschrieben 13. April 2010 problem hierbei wäre dann aber, dass ich so a gschmarri rausbekomm: �abc� / 5 (bezüglich der zeile mit "std:.wcout << pwcstr....") der haut dann irgend ein 4Byte-Zeichen einfach vorne an. bezüglich speicherung hab ichjetzt statt fwrite fputws benutzt jetz bekomm ich auch a anständige utf8-codierte datei (laut geany). jedoch wurde das "ö" mit einem "?" (NICHT zeichen ->� ! nur ein normales "?") ausgetauscht. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 13. April 2010 Teilen Geschrieben 13. April 2010 der haut dann irgend ein 4Byte-Zeichen einfach vorne an.Das ist ein BOM, das ist da durchaus angebracht. Wenn du es nicht willst, lass es weg. bezüglich speicherung hab ichjetzt statt fwrite fputws benutzt jetz bekomm ich auch a anständige utf8-codierte datei (laut geany).Moment, was ist jetzt dein Ziel? Wide Character oder UTF-8? Beides gleichzeitig ist Quatsch. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 13. April 2010 Autor Teilen Geschrieben 13. April 2010 das was gespeichert wird is ja UTF-8 (kenne keine datei, welche in WCHAR_T gespeichert ist (da es ja datentyp ist) das mit speichern ist ja eh nur zur prüfung gedacht. eigentlich wollt ich ja mit dem convertierten string ja weiterarbeiten. jedoch könnt ich einfach nach konvertierung wirklich das BOM-zeichen abschneiden Bezüglich des speicherleaks ist es dann angebrachd pcstr = pcstr+1 zu machen? ansonsten konvertier ich es sofort in wstring un entfern es dann darüber ... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 13. April 2010 Teilen Geschrieben 13. April 2010 das was gespeichert wird is ja UTF-8 (kenne keine datei, welche in WCHAR_T gespeichert ist (da es ja datentyp ist)Den Satz verstehe ich überhaupt nicht. UTF-8 ist keine Wide-Character-Codierung. Wenn du Wide Character hast, hast du nicht UTF-8. Das schließt sich gegenseitig aus. Bezüglich des speicherleaks ist es dann angebrachd pcstr = pcstr+1 zu machen? Ich vermute, dass irgendwo in deiner iconvert-Funktion irgendwie Speicher reserviert wird. Den musst du natürlich wieder freigeben. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 13. April 2010 Autor Teilen Geschrieben 13. April 2010 (bearbeitet) Den Satz verstehe ich überhaupt nicht. UTF-8 ist keine Wide-Character-Codierung. Wenn du Wide Character hast, hast du nicht UTF-8. Das schließt sich gegenseitig aus. naja es is ja so: ich habe jetzt wchar_t string. den hab ich ja mit dem iconv befüllt, indem ich die source-zeichenkette in UTF-32 umcodiert habe. nun hab ich über fputwc in eine datei gespeichert. DIESE datei ist laut geany UTF-8 codiert (meint zumindest der statusbar). das war meine aussage ^^ (zudem hab ja gesagt, es gibt ja keine konvertierung von Textdateien in "WCHAR") Keine Ahnung. Ich vermute, dass irgendwo in deiner iconvert-Funktion irgendwie Speicher reserviert wird. Den musst du natürlich wieder freigeben. K bezüglich des muss ich wohl a lösung finden. Das problem (wenn man das BOM-zeichen aussen vor lässt) was ich noch hab is dann noch die rückconvertierung in z.B. UTF-8 ... die funktion zur konvertierung bleibt bei mir in ner loop schleife hängen, welche erst rausgeht, wenn die länge des Inputs (3 parameter von der iconv_funktion. laut manpage "size_t *inbytesleft"). kann es sein, dass hier wegen der UTF-32 Codierung die richtige länge nicht erkennt wird bzw. durch die codierung auf 32bit für ein zeichen dies zu problemen führt? hab irgendwo (webseite) gesehen, dass durch die erweiterung hinter jedem zeichen dann ein "\0" stehen würd. ... Bearbeitet 13. April 2010 von Shamharoth Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 13. April 2010 Teilen Geschrieben 13. April 2010 nun hab ich über fputwc in eine datei gespeichert.Warum tust du das? fputwc nimmt in Abhängigkeit der aktuellen Locale wieder eine Umcodierung in Multibyte vor. (zudem hab ja gesagt, es gibt ja keine konvertierung von Textdateien in "WCHAR")WCHAR ist auch keine Codierung. Aber du kannst Textdateien natürlich in eine Wide-Character-Codierung wie UTF-32 konvertieren. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 13. April 2010 Autor Teilen Geschrieben 13. April 2010 Warum tust du das? fputwc nimmt in Abhängigkeit der aktuellen Locale wieder eine Umcodierung in Multibyte vor.. ok ... mist :/ ... welche methode würdest du empfehlen? (wfwrite (oder ähnlich) gibts ja nur bei windows) un bei wfprint(ffile,L"%s", pwcstr); hat er bei mir nur den ersten byte geschrieben.) blöd is nur momentan ich kann ja auch wcstombs() nicht benutzen, da er bei den umlauten raushaut und -1 zurückgibt (ich glaub das hat ich schon am anfang des threads mit erwähnt). Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 14. April 2010 Autor Teilen Geschrieben 14. April 2010 (bearbeitet) so ich hab mal 123abc in utf32 convertiert und als char ausgeben lassen. Dabei hab ich alle '\0' als [] angezeigt. ergebnis: ��[][]2[][][]2[][][]3[][][]a[][][]b[][][]c[][][][][][][] (BOM ist noch dabei) bei abcü kommt ��[][]a[][][]b[][][]c[][][]�[][][][][][][] jetz ist die frage: wenn ich alle 0 in viererblöcken lösch bis auf den aller letzten, ist dann noch gegeben, dass es richtig convertiert (dann is es ja genaugenommen a MB char array. Aber ob dies eine konforme "beschneidung" ist bezweifle ich irgendwie. Irgendwie MUSS ja UTF-32 nach "unten" konvertierbar sein. edit: ich hab mir mal schnell folgende funktion zusammengedacht: void * UTF32toUTF8(char *sString) { DWORD pos = 0; DWORD newpos = 0; while(1) { DWORD temppos = 0; if(sString[pos+temppos] == 0 && sString[pos+temppos+1] == 0 && sString[pos+temppos+2] == 0 && sString[pos+temppos+3] == 0) { sString[pos+temppos] = 0; break; } for(;temppos < 4; temppos++) { if(sString[pos+temppos] == 0) break; sString[newpos] = sString[pos+temppos]; newpos++; } pos+=4; } } Bearbeitet 14. April 2010 von Shamharoth Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 14. April 2010 Teilen Geschrieben 14. April 2010 ergebnis:Sieht doch gut aus. jetz ist die frage: wenn ich alle 0 in viererblöcken lösch bis auf den aller letzten, ist dann noch gegeben, dass es richtig convertiert (dann is es ja genaugenommen a MB char array.Nein. Wie willst du denn "ab" von "慢" (Unicode-Zeichen 0x6162) unterscheiden? UTF-32 ist keine Multibyte-Codierung mit "Zusatznullen". Die Tatsache, dass jedes Zeichen durch genau 32 Bits codiert wird, ist eine für die Decodierung wichtige Zusatzinformation. Wenn du die Nullbytes entfernst, kann man nicht mehr rekonstruieren, wo im Datenstrom ein neues Zeichen anfängt. Multibyte-Codierungen benutzen zusätzliche Bits für genau diese Information. Irgendwie MUSS ja UTF-32 nach "unten" konvertierbar sein.Ist es ja auch. Aber so einfach ist es dann doch nicht. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 14. April 2010 Autor Teilen Geschrieben 14. April 2010 Sieht doch gut aus. Nein. Wie willst du denn "ab" von "慢" (Unicode-Zeichen 0x6162) unterscheiden? haha:) ich hab dein post gelesen und wollte mit deinem post als zitat antworten, aber in zwischenzeit hast etwas editiert. beim öffnen des editors hab ich mir gedacht "huch wo kommt plötzlich der satz her?" .. ach ja es lebe die zeit ^^ ... zum quote: hm verständlich .... UTF-32 ist keine Multibyte-Codierung mit "Zusatznullen". Die Tatsache, dass jedes Zeichen durch genau 32 Bits codiert wird, ist eine für die Decodierung wichtige Zusatzinformation. Wenn du die Nullbytes entfernst, kann man nicht mehr rekonstruieren, wo im Datenstrom ein neues Zeichen anfängt. Multibyte-Codierungen benutzen zusätzliche Bits für genau diese Information. ... Ist es ja auch. Aber so einfach ist es dann doch nicht. k das bedeutet ich müssd mir a funktion suchen die das machd. ... für alphanumerische zeichen is es nich schlimm einfach die "0"-Bytes zu cutten ... jedoch will ich ja doch noch die anderen zeichen beibehalten warum gibt es keine standartfunktion die das machen kann? warum kann es iconv nicht? blödes iconv! *schachtel mit "iconv"-aufschrift tret* falls ich diesbezüglich a funktion gefunden hab, meld ich mich (es seidenn es kennt jemand die funktion schon. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shamharoth Geschrieben 14. April 2010 Autor Teilen Geschrieben 14. April 2010 hab momentan ne gaaaaaaaaanz blöde idee (weshalb ich jetzt ma fragen müssd) ... alle MB-chars sind ja so codiert, dass diese (wenn man char in unsigned int umwandelt) >128 sind ... je nach anzahl der dazugehörigen Zeichen kann man auch sagen wieviele elemente zum MB-zeichen gehören. dann kann ich mit glück so machen, dass ich für den bereich, der den inhalt ändert, gar nicht in UTF32 umwandle und nur zur prüfung ohne änderung des eingabetextes das mach. .... somit hab ich kein problem mit der rückformatierung. .... etwas problematischer wird dann hald, dass ich z.b. MB-zeichen weglöschen muss .... sollte jedoch eifnacher sein als UTF32 in UTF8 zu konvertieren ;D .... muss nochmal überlegen ^^ Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.