Writefile und Unicode



  • Hallo,

    ich übergebe an meine Funktion einen String und will diesen dann in eine Datei schreiben:

    int WriteCSV(LPTSTR sData1, LPTSTR sData2) {
    	TCHAR BatchFile[MAX],BatchContent[MAX],TempPath[256];
    	HANDLE hFile;
    	DWORD NumberOfBytesWritten;
    	FILE *f = NULL;
    	int err;
    
    	memset(BatchFile,0,MAX);
    	memset(BatchContent,0,sizeof(BatchContent));
    	memset(TempPath,0,sizeof(TempPath));
    
    	GetTempPath(sizeof(TempPath), TempPath);
    
    	_swprintf(BatchFile,_T("%ssn.bat"), TempPath);
    
    	hFile = CreateFile(BatchFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    
    	if(hFile == INVALID_HANDLE_VALUE)
    		return 0;
    
    	_swprintf( BatchContent, _T("%s;%s"), sData1, sData2);
    
    	WriteFile(hFile, BatchContent, _tcslen(BatchContent), &NumberOfBytesWritten, NULL);
    
    	CloseHandle(hFile);
    
    }
    

    Die Datei wird auch geschrieben, nur ist die Datei so aufgebaut das nach jedem Symbol/Zeichen ein Leerzeichen kommt, was so nicht gewollt ist.
    Ich vermute das hängt damit zusammen das hängt damit zusammen, das ich das Projekt Unicode fähig mache.
    Bitte um kurze Erklären, danke.

    Grüße



  • WriteFile schreibt erstmal nur Bytes. Nun schreibst du aber direkt einen UTF-16 String in die Datei. UTF-16 Strings Stellen aber jedes Zeichen mit 2Bytes dar, dadurch hat der String intern einiges an Leerbytes, die laden alle mit in der Datei.
    Wenn ein Programm diese Datei dann falsch erkennt - z.B. als ASCII behandelt - Dann wirst du auch viele Nullbytes im String finden.
    Im übrigen schreibst du nur die Hälfte aller Bytes in die Datei, weil du doppelt so viele Bytes schreiben müsstest wie der String Zeichen hat.

    int WriteCSV(LPTSTR sData1, LPTSTR sData2) {
        TCHAR BatchFile[MAX],BatchContent[MAX],TempPath[256];
        HANDLE hFile;
        DWORD NumberOfBytesWritten;
        FILE *f = NULL;
        int err;
    
        memset(BatchFile,0,MAX); //Auch hier sizeof nutzen, es sind mehr Bytes (um genau zu sein MAX*2)
        memset(BatchContent,0,sizeof(BatchContent));
        memset(TempPath,0,sizeof(TempPath));
    
        GetTempPath(sizeof(TempPath), TempPath); //Hier dagegen ist die Anzahl der Zeichen gefragt, sizeof ist also falsch und führt zu einem Overflow
    
        _swprintf(BatchFile,_T("%ssn.bat"), TempPath);
    
        hFile = CreateFile(BatchFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    
        if(hFile == INVALID_HANDLE_VALUE)
            return 0;
    
        _swprintf( BatchContent, _T("%s;%s"), sData1, sData2);
    
        WriteFile(hFile, BatchContent, _tcslen(BatchContent), &NumberOfBytesWritten, NULL);
    
        CloseHandle(hFile);
    
    }
    

    Du musst den String vor dem Schreiben umwandeln wenn du in der Datei keinen UTF-16 String willst, hier mal auf die schnelle ein Beispiel:

    char* ToUTF8(LPCWSTR str)
    {
    	int strLen = wcslen(str);
    	int newLen = WideCharToMultiByte(CP_UTF8, 0, str, strLen, NULL, 0, NULL, NULL);
    
    	char* strnew = new char[newLen + 1];
    	strnew[newLen] = '\0';
    	WideCharToMultiByte(CP_UTF8, 0, str, strLen, strnew, newLen, NULL, NULL);
    
    	return strnew;
    }
    
    int WriteCSV(LPTSTR sData1, LPTSTR sData2) 
    {
        TCHAR BatchFile[256],BatchContent[256],TempPath[256];
        HANDLE hFile;
        DWORD NumberOfBytesWritten;
        HANDLE *f = NULL;
        int err;
    
        memset(BatchFile,sizeof(BatchFile)));
        memset(BatchContent,0,sizeof(BatchContent));
        memset(TempPath,0,sizeof(TempPath));
    
        GetTempPath(256, TempPath);
    
        swprintf(BatchFile,L"%ssn.bat", TempPath);
    
        hFile = CreateFileW(BatchFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    
        if(hFile == INVALID_HANDLE_VALUE)
            return 0;
    
    	_swprintf( BatchContent, L"%s;%s", sData1, sData2);
    
    	char* utf8Str = ToUTF8(BatchContent);
    	WriteFile(hFile, utf8Str, strlen(utf8Str), &NumberOfBytesWritten, NULL);
    	delete[] utf8Str;
    	CloseHandle(hFile);
    }
    

    Ist nicht sonderlich schön, zeigt aber wie man einen Unicode String als UTF-8 speichert. Vorausgesetzt ich habe bei der Benutzung von WideCharToMultiByte keinen Fehler gemacht.



  • Als Erstes würde mir

    not all control paths return a value

    auffallen.
    Ohne mir den code überhaupt durchgelesen zu haben, sondern nur die Struktur.


Log in to reply