String mit ReadFile lesen
-
Hallo Leute.
Ich möchte einen Unicode-String auslesen.
Dazu habe ich was vorbereitet, funktioniert aber nicht!
Der LPWSTR enthält nur hyroglyphen. Das kann damit zusammenhängen, dass ein WCHAR multiple-byte ist und die textdatei nicht. aber wie lese ich denn nun vernünftig aus? und zwar u8nbedingt mit der nativen winapi!void LoadFilter(HINSTANCE hInstance, LPWSTR lpFilter) { WCHAR name[MAX_PATH + 1]; LoadString(hInstance, IDS_FILTER, name, MAX_PATH); // build path to read file WCHAR path[MAX_PATH + 1]; GetModuleFileName(NULL, path, MAX_PATH); PathRemoveFileSpec(path); PathAppend(path, name); HANDLE hFile = CreateFile(path, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { lpFilter[0] = L'\0'; return; } WCHAR buffer[MAX_READ_FILTER + 1]; DWORD dwRead; if (!ReadFile(hFile, buffer, MAX_READ_FILTER, &dwRead, NULL)) { lpFilter[0] = L'\0'; return; } lstrcpy(lpFilter, buffer); CloseHandle(hFile); }
Vielen Dank schonmal.
-
Was denn?
Hat denn keiner ne Ahnung?
Oder liest man Texte generell nicht mit ReadFile aus?Fakt ist, ich benötige ein LPWSTR, egal ob die Textdatei ein Ansi- oder Unicode-Format hat oder was auch immer.
Danke.
-
MultiByteToWideChar
-
Gut, danke. Aber was, wenn die Text-Datei ein ANSI-File ist, wie überprüft man das?
-
-
Normalerweise haben Unicode-Textdateien eine Markierung. Wenn keine da ist, dann ist es eine Ansi- oder ASCII-Datei.
-
Danke. Könntet ihr meinen COde so abbessern, dass er überprüft, um welches Format es sich handelt? Ich komme mit diesem "big endian" oder so net klar...
Danke.
-
Könntet ihr meinen COde so abbessern, dass er überprüft, um welches Format es sich handelt?
nein
-
na gut, ihr habt ja recht...
ich habe jetzt mal was selber versucht, das funktioniert auch mit ANSI, UTF-8, UNICODE, aber eben nicht mit UNICODE big endian.
void LoadFilter(HINSTANCE hInstance, LPWSTR lpFilter) { WCHAR name[MAX_PATH + 1]; LoadString(hInstance, IDS_FILTER, name, MAX_PATH); // build path to read file WCHAR path[MAX_PATH + 1]; GetModuleFileName(NULL, path, MAX_PATH); PathRemoveFileSpec(path); PathAppend(path, name); HANDLE hFile = CreateFile(path, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { lpFilter[0] = L'\0'; return; } char buffer[MAX_READ_FILTER * sizeof(WCHAR) + 1]; DWORD dwToRead = MAX_READ_FILTER * sizeof(WCHAR) + 1; DWORD dwRead; if (!ReadFile(hFile, buffer, dwToRead, &dwRead, NULL)) { lpFilter[0] = L'\0'; return; } WCHAR filter[MAX_READ_FILTER + 1]; if (buffer[0] >= 0) // ansi { MultiByteToWideChar(CP_ACP, 0, buffer, sizeof(buffer), filter, MAX_READ_FILTER); } else if (buffer[0] == -17) // utf-8 { MultiByteToWideChar(CP_UTF8, 0, buffer+1, sizeof(buffer)-1, filter, MAX_READ_FILTER); } else if (buffer[0] == -1) // unicode { memcpy(filter, buffer+2, sizeof(buffer)-2); } else if (buffer[0] == -2) // unicode big endian { // was soll ich denn hier machen? // das memcpy vom unicode gibt nur hyroglyphen. } MessageBox(NULL, filter, NULL, MB_OK); CloseHandle(hFile); }
Was soll ich in die auskommentierte stelle reinpacken? Wie soll ich das machen?
Danke.
-
du könntest einfach die 2 bytes eines words tauschen.
davon abgesehen würde ich auch das 2. byte des byte-order-markers prüfen.
-
Viele Unicode-Dateien haben gar keinen BOM. Auch die Funktionen im .net-framework z.B. schreiben per-default keinen BOM.
-
Warum das 2.?
lohnt es sich, beide zu prüfen?
Welche daten haben die des 2.?
Danke.
-
Warum das 2.?
lohnt es sich, beide zu prüfen?
Welche daten haben die des 2.?
Danke.http://en.wikipedia.org/wiki/Byte_Order_Mark
Und wenn kein BOM vorhanden ist kann man nurnoch versuchen "gut zu raten", oder den User zu fragen.
-
jetz hab ich hier hex-zahlen.
Ist es besser == 0xEF zu überprüfen, als mit den Zahlen?
-
das habe ich jetzt:
if ((buffer[0] == -17) && (buffer[1] == -69)) // utf-8 { MultiByteToWideChar(CP_UTF8, 0, buffer+3, sizeof(buffer)-3, filter, MAX_READ_FILTER); } else if ((buffer[0] == -1) && (buffer[1] == -2)) // unicode { memcpy(filter, buffer+2, sizeof(buffer)-2); } else if ((buffer[0] == -2) && (buffer[1] == -1)) // unicode big endian { for (int i = 2; i < sizeof(buffer); i+=2) { // swap bytes char buff = buffer[i]; buffer[i] = buffer[i + 1]; buffer[i + 1] = buff; } memcpy(filter, buffer+2, sizeof(buffer)-2); } else { MultiByteToWideChar(CP_ACP, 0, buffer, sizeof(buffer), filter, MAX_READ_FILTER); }
Auf Raten kein bock, wenn das nicht ordnungsgemäß gemacht wird, haben die pech gehabt...
danke.
-
Jo sieht nicht ganz verkehrt aus.
Was die Hexzahlen angeht: wenn's nur mit MSVC und einstellung "default char unsigned = false" gehen soll dann müsste das so passen.
Ansonsten vielleicht lieber "(int(buffer[0]) & 0xFF) == 0xFF" oder sowas verwenden.