UTF8 zu wchar_t konvertierungs Problem



  • Hallo,

    ich möchte gerne eine Funktion bauen, die mir eine Datei die UTF8 kodiert ist, einließt und als wchar_t abspeichert. Diese sollte nach möglichkeit auf Linux und Windows laufen. Mithilfe von WinAPI Funktionen habe ich es schon hinbekommen, allerdings hänge ich noch an der auf beiden lauffähige Version locale_to_wchar.

    Hier mal mein bisheriger Code:

    #include <stdio.h>
    #include <windows.h>
    #include <locale.h>
    
    bool LocaleToWide( LPCSTR lpszAnsi, LPWSTR *lpszWide )
    {
    	int iWideLen = 0;
    
    	iWideLen = MultiByteToWideChar( CP_UTF8, 0, lpszAnsi, -1, NULL, 0 ); 
    	if( iWideLen == 0 )
    	{
    		MessageBox( NULL, "Fehler MultiByteToWideChar 1", "Fehler", MB_OK );
    		return false;
    	}
    
    	*lpszWide = (LPWSTR) malloc( iWideLen * sizeof(WCHAR) +1 );
    	if( *lpszWide == NULL )
    	{
    		MessageBox( NULL, "Fehler MultiByteToWideChar 2", "Fehler", MB_OK );
    		return false;
    	}
    
    	if( MultiByteToWideChar( CP_UTF8, 0, lpszAnsi, -1, *lpszWide, iWideLen ) != 0 )
    		return true;
    	else
    		return false;
    }
    
    wchar_t * locale_to_wchar(char * str)
     {
    	wchar_t * ptr;
    	size_t s;
    
    	/* first arg == NULL means 'calculate needed space' */
    	s = mbstowcs(NULL, str, 0);
    
    	/* a size of -1 is triggered by an error in encoding; never
    	   happen in ISO-8859-* locales, but possible in UTF-8 */
    	if(s == -1)
    		return(NULL);
    
    	/* malloc the necessary space */
    	if((ptr = (wchar_t *)malloc((s + 1) * sizeof(wchar_t))) == NULL)
    		return(NULL);
    
    	/* really do it */
    	mbstowcs(ptr, str, s);
    
    	/* ensure NULL-termination */
    	ptr[s] = L'\0';
    
    	/* remember to free() ptr when done */
    	return(ptr);
     }
    
    int main()
    {
    	FILE *	pFile = NULL;
    	long	FileSize = 0;
    	char *	SrcFile	= NULL;
    	LPWSTR	wSrcFile;
    
    	pFile = fopen( "C:\\unicode-example-UTF8.txt", "rb" );
    	if( pFile == NULL )
    		return 0;
    
    	if( fseek( pFile, 0, SEEK_END ) != 0 )
    		return 0;	
    
    	if( (FileSize = ftell( pFile )) == -1 )
    		return 0;
    
    	rewind( pFile );
    
    	SrcFile = (char*) malloc( FileSize + sizeof(char));
    	if( SrcFile == NULL ) 
    		return 0;
    
    	memset( SrcFile, 0, sizeof(SrcFile));
    
    	if( fread( SrcFile, sizeof(char), FileSize, pFile ) == 0 )
    		return 0;
    
    	// Für Posix/Linux
    	/*
    	setlocale( LC_ALL, "de_DE.UTF-8" );		// Oder en_US.UTF-8
    
    	wSrcFile = locale_to_wchar( SrcFile );
    	*/
    	// Für Windows
    	LocaleToWide( SrcFile, &wSrcFile );
    
    	MessageBoxW( NULL, wSrcFile, L"UTF8 Datei", MB_OK );
    
    	free( wSrcFile );
    	return 0;
    }
    

    Danke schonmal

    Gruß
    yogle



  • und dein problem?

    wenn du binaeres utf8 zu unicode dekodieren sollst, dann lies dir mal durch, was utf8 ist.



  • c.rackwitz schrieb:

    und dein problem?

    wenn du binaeres utf8 zu unicode dekodieren sollst, dann lies dir mal durch, was utf8 ist.

    ???

    Mein Problem habe ich oben beschrieben und ich habe mir durchgelesen was utf8 ist! Bei wchar_t hat jedes Zeichen 2 Byte Platz bei utf8 ist es je nach Zeichen unterschiedlich. So und diese utf8 Zeichen sollen jetzt in einem wchar_t Array gespeichert werden.

    Ich habe es in der LocaleToWide Funktion ja schon hinbekommen, allerdings verwendet diese WinAPI-Funktionen welche auf einem Linux System nicht vorhanden sind. Und ich bekomme nun eben nicht die locale_to_wchar Funktion zu laufen, die ich brauche, da diese keine WinAPI Funktionen benützt. Ich weiß nicht wie ich mbstowcs sagen kann, dass die Zeichen im char* String utf8 Zeichen sind, was man tun muss sonst kommt Mist raus!



  • die funktionsbeschreibungen sagen mir persoenlich garnichts.

    an deiner stelle wuerd ich mir ne eigene funktion schreiben, um utf8 zu dekodieren. dann hast du naemlich erstmal ne grundlage und kannst spaeter immernoch nach c stdlib oder api funktionen gucken.



  • Ich soll mir erst ne eigene Funktion schreiben und danach dann nach einer schon vorhanden schauen, die genau das gleiche macht? Also da weiß ich meine Zeit besser zu nutzen.

    Wenn dir die Funktionen nichts sagen:

    www.mkssoftware.com/docs/man3/mbstowcs.3.asp

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_17si.asp

    Bei MultiByteToWideString kann ich angeben, dass der Input String aus UTF8 Zeichen besteht. Und für mbstowcs fehlt mir diese Möglichkeit und ich weiß nicht wie ich das irgendwo einstellen kann.



  • probiers doch mal mit
    http://www.cppreference.com/stddate/setlocale.html

    ich an deiner stelle wuerde nicht so krampfhaft nach loesungen suchen, sonder mir eine machen. dann waerst du naemlich laengst fertig.



  • yogle schrieb:

    /*
    setlocale( LC_ALL, "de_DE.UTF-8" );		// Oder en_US.UTF-8
    
    wSrcFile = locale_to_wchar( SrcFile );
    */
    

    c.rackwitz schrieb:

    probiers doch mal mit
    http://www.cppreference.com/stddate/setlocale.html

    Hmm okay...

    Ich denke nicht, dass ich krampfhaft nach einer Lösung suche, aber warum sollte ich das Rad neu erfinden, wenn es diese Funktion schon lange gibt?

    Ich weiß dass ich über setlocale() die aktuelle Codepage einstellen muss, doch habe ich es eben noch nicht hinbekommen. Die MessageBox zeigt nur Ansi-Zeichen
    an. Wenn ich aber die Funktion LocaleToWide (eigene Funktion!) verwende werden alle UTF8 Zeichen korrekt zu Unicode (UCS-2 oder UTF-16 wie du willst) umgewandelt und angezeigt.




Anmelden zum Antworten