Brauche iconv erklärung



  • Hi

    Ich kämpfe grade mit iconv.

    // initialize -> convert UTF-8 to UTF-32
    iconv_t cd = iconv_open ("UTF-32", "UTF-8");
    
    int outsize = 8; // outputsize (1 char = 4 byte + ???  maybe \0 ?)
    size_t inputsize = 1; // inputsize
    size_t outputsize = outsize;
    char* input = (char *) "a";
    char* output = new char[outsize];
    memset (output, 0x00, outsize);
    
    // convert utf8 input to utf32 output
    size_t erg = iconv (cd, &input, &inputsize, &output, &outputsize);
    
    // close iconv
    iconv_close (cd);
    
    printf ("Inputsize: %d\n", inputsize);
    printf ("Outputsize: %d\n", outputsize);
    printf ("Erg: %d\n", erg);
    
    // print output (every byte in hex)
    for (int i = 0; i < outsize; i++)
    {
    	printf ("%2X\n", (unsigned char) output[i]);
    }
    
    delete[] output;
    

    Output ist folgender:

    Inputsize: 0
    Outputsize: 0
    Erg: 0
     0
     0
     0
     0
    49
     8
     2
     0
    

    Ok nun könnte man meinen 4 Nullbytes (Terminierung?) + das "a" in UTF32.
    Ist aber nicht so denn schreibe ich statt dem "a" ein "g" oder sonst was, dann bekomme ich den selben output.

    Ok -> dann sind die hinteren 4 bytes eben die Terminierung (oder sonst was ka wo die herkommen) und beim umwandeln geht was schief was die ersten 4 Nullbytes erklären würde.

    Also Input auf auf 2 Zeichen erhöht -> sollte dann im output ja 8 nullbytes + die 4 undefinierten bytes ergeben.

    int outsize = 12; // outputsize (1 char = 4 byte + ???  maybe \0 ?)
    size_t inputsize = 2; // inputsize
    size_t outputsize = outsize;
    char* input = (char *) "af";
    char* output = new char[outsize];
    

    Output:

    Inputsize: 0
    Outputsize: 0
    Erg: 0
    49
     8
     2
     0
     0
     0
     0
     0
     0
     0
     0
     0
    

    Ähm ja -> 😕

    Dann eben noch ein Test mit 3 Buchstaben

    int outsize = 16; // outputsize (1 char = 4 byte + ???  maybe \0 ?)
    size_t inputsize = 3; // inputsize
    size_t outputsize = outsize;
    char* input = (char *) "asd";
    char* output = new char[outsize];
    memset (output, 0x00, outsize);
    

    Output:

    Inputsize: 0
    Outputsize: 0
    Erg: 0
     0
     0
     0
     0
    41
     8
     2
     0
     0
     0
     0
     0
     0
     0
     0
     0
    

    WTF

    Ich überseh in den 26 Codezeilen sicher grade was triviales nur was?

    iconv scheint richtig zu funktionieren (bis auf das outputarray).
    Inputsize und outputsize werden korrekt auf 0 decrementiert und die Rückgabe der Funktion ist nicht -1 -> kein Fehler
    0 ist sie deshalb weil

    The iconv function returns the number of characters converted in a non-reversible way during this call; reversible conversions are not counted.

    http://www.gnu.org/software/libiconv/documentation/libiconv/iconv_open.3.html
    http://www.gnu.org/software/libiconv/documentation/libiconv/iconv.3.html

    Weiß wer was ich falsch mache?

    Keros



  • Habs gefunden. Ich muss mir bevor ich die Funktion aufrufe den output pointer merken oder ihn nach dem Aufruf wieder zurücksetzen.

    Hier mal meine convertfunktion

    int Lable_Tag_Write::convertToUTF32 (std::string text, std::vector<unsigned char>* utf32text)
    {
    	unsigned int textlen = getUTF8Len (text);
    	unsigned int outputlen = textlen * 4;
    
    	size_t outputleft = outputlen;
    	size_t inputleft = text.length ();
    
    	char input[text.length ()];
    	char output[outputlen];
    	char* outputshift = output;
    	char* inputshift = input;
    
    	memset (output, 0x00, outputlen);
    	memcpy (input, text.data (), text.length ());
    
    	// initialize -> convert UTF-8 to UTF-32
    	iconv_t cd = iconv_open ("UTF-32BE", "UTF-8");
    	if (cd == (iconv_t) -1)
    	{
    		return -1;
    	}
    
    	// convert utf8 input to utf32 output
    	size_t erg = iconv (cd, &inputshift, &inputleft, &outputshift, &outputleft);
    	if (erg == (size_t) -1)
    	{
    		return -1;
    	}
    
    	// close iconv
    	iconv_close (cd);
    
    	utf32text->resize (outputlen, 0x00);
    	std::copy (output, output + outputlen, utf32text->begin ());
    
    	return 0;
    }
    

    Keros


  • Administrator

    Nur so als Tipp vielleicht. iconv ist ja für C gedacht, diese Bibliothek wäre für C++ gedacht:
    http://utfcpp.sourceforge.net/

    Grüssli


Anmelden zum Antworten