Probleme beim Schreiben einer Datei ins UTF8-Format
-
Hallo.
Wir programmieren grade als Teil einer Arbeit für die Uni einen UTF8<=>UTF16 Konverter. Ich bin momentan an dem UTF8-Teil dran. Dazu wird (momentan zu Testzwecken) eine UTF8 Textdatei eingelesen, in Unicode umgewandelt, und von da wieder in eine UTF8 Datei geschrieben. Das Problem ist jetzt, dass die Datei zwar wieder in UTF8 geschrieben werden, allerdings fehlt der erste Buchstabe und z.B. nach einem Umlaut fehlt ein Buchstabe ("Lösung" wird zu "Löung").Hier erstmal der Code, viel Sinn macht der natürlich momentan nicht (da UTF8 nach UTF8 umgewandelt wird), das ist momentan aber alles nur zum Testen. Die einzelnen Ausgaben sind auch nur zum Überwachen da.
Die eingelesene Datei ist diese (Rechtsklick, Speichern unter).
#include <stdio.h> #include <stdlib.h> long int convertUTF8ToUnicode(FILE*); long int convertUnicodeToUTF8(long int); int main(int argc, char* argv[]) { FILE* fileHandler; fileHandler = fopen("UTF8Test.txt", "r"); //Open the input file while(!feof(fileHandler)) { convertUTF8ToUnicode(fileHandler); } } long int convertUTF8ToUnicode(FILE* fileHandler){ unsigned char charBuffer[1], helpBuffer[4]; //We put the characters into a new array. long int unicodeValue; //This will be the returned Unicode value. fread(&charBuffer, sizeof(char), 1, fileHandler); //Read the character into the array. if (charBuffer[0] < 0x80) { unicodeValue = charBuffer[0]; //The first 128 chars of UTF8 are pure Unicode anyway, no need to convert it. } else if (charBuffer[0] < 0xc0) { return -1; //Does the byte start with 11xxxxxx? If yes cancel it, since no such byte exists in UTF8. } else if (charBuffer[0] < 0xe0) { //Consists the char of two bytes? fread (&helpBuffer, sizeof(char), 2, fileHandler); unicodeValue = ( (charBuffer[0]&0x1f ) << 6 ) + (helpBuffer[0]&0x3f ); } else if (charBuffer[0] < 0xf8) { //Consists the char of three bytes? fread (&helpBuffer, sizeof(char), 3, fileHandler); unicodeValue = ( (charBuffer[0]&0x0f ) << 12 ) + ((helpBuffer[0]&0x3f ) << 6 ) + (helpBuffer[1]&0x3f ); } else if (charBuffer[0] < 0xfc) { //Consists the char of four bytes? fread (&helpBuffer, sizeof(char), 4, fileHandler); unicodeValue = ((charBuffer[0] & 0x07) << 18) + ((helpBuffer[1]&0x3f ) << 12 ) + ((helpBuffer[1]&0x3f ) << 6 ) + (helpBuffer[2]&0x3f ); } printf("\nUnicode Value: %d", unicodeValue); convertUnicodeToUTF8(unicodeValue); } long int convertUnicodeToUTF8(long int unicodeValue){ unsigned char charBuffer[4]; //We put the characters into a new array. int bytesToWrite; printf("\nUnicode Value in UTF8 Methode: %d", unicodeValue); if(unicodeValue < 0x80) { //1 Byte will be used charBuffer[0] = unicodeValue; //The first 128 chars of Unicode are pure UTF8 anyway, no need to convert it. printf("\n1 Byte: %d",charBuffer[0]); bytesToWrite=1; } else if (unicodeValue < 0x800) { //2 Bytes will be used charBuffer[0] = (unicodeValue >> 6) | 0xc0; charBuffer[1] = (unicodeValue & 0x3f) | 0x80; printf("\n2 Byte: %d %d",charBuffer[0], charBuffer[1]); bytesToWrite=2; } else if (unicodeValue < 0x10000) { //3 Bytes will be used charBuffer[0] = (unicodeValue >> 12) | 0xe0; charBuffer[1] = ((unicodeValue >> 6) & 0x3f) | 0x80; charBuffer[2] = (unicodeValue & 0x3f) | 0x80; printf("\n3 Byte: %d %d %d",charBuffer[0], charBuffer[1], charBuffer[2]); bytesToWrite=3; } else if (unicodeValue < 0x200000) { //4 Bytes will be used charBuffer[0] = (unicodeValue >> 18) | 0xf0; charBuffer[1] = ((unicodeValue >> 12) & 0x3f) | 0x80; charBuffer[2] = ((unicodeValue >> 6) & 0x3f) | 0x80; charBuffer[3] = (unicodeValue & 0x3f) | 0x80; printf("\n4 Byte: %d %d %d %d",charBuffer[0], charBuffer[1], charBuffer[2], charBuffer[3]); bytesToWrite=4; } else{ printf("fehler"); } FILE *fOut; fOut = fopen ("test.txt", "a"); fwrite (&charBuffer, sizeof(char), bytesToWrite, fOut); fclose(fOut); }
Hat jemand eine Idee, woran das liegen könnte? Ich hoffe ich hab nix vergessen, sonst fragt einfach.
-
Ok, habs gelöst. Es wurde immer ein Byte zuviel in den helpBuffer geschrieben. Ich hab jetzt bei
fread (&helpBuffer, sizeof(char), x, fileHandler);
(x = Anzahl an Bytes)
jeweils 1 von x abgezogen, und es funktioniert.