2016-06-02 9 views
2

Zunächst einmal: Ich weiß, es gibt ähnliche Themen für C++, aber ich bin neugierig auf Standard C, und ich glaube nicht, dass mein Problem mit früheren Problemen zusammenhängt.Drucken/Schreiben wchar_t?

Ich versuche Unicode-Unterstützung für ein einfaches Programm zu implementieren, das den Benutzer nur auffordert, ein Verzeichnis über einen Ordnerbrowser auszuwählen und es dann an ein anderes Programm weiterzuleiten (nur an den ersten Teil). Wenn Sie jedoch versuchen, den empfangenen Pfad in eine Datei zu schreiben, wird eine 0-Byte-Datei erstellt. Und wenn es mit wprintf_s ausgedruckt wird, erscheinen Nicht-ASCII-Zeichen als Fragezeichen. Ich glaube nicht, dass es ein undefiniertes Verhalten oder irgendetwas gibt, da ich die Dokumentation doppelt überprüft habe. Was mache ich falsch?

Der Code sieht derzeit wie folgt aus (nur das Nötigste für strenge Testbedingungen):

#define UNICODE 
#define _UNICODE 

#include <windows.h> 
#include <shlobj.h> 
#include <stdio.h> 

int main() 
{ 
    BROWSEINFOW bi = { 0 }; 
    LPITEMIDLIST pidl; 
    wchar_t path[MAX_PATH]; 
    pidl = SHBrowseForFolderW(&bi); 
    SHGetPathFromIDListW(pidl, path); 
    wprintf_s(L"%s\n", path); 
    return 0; 
} 

Der obige Code druckt es regelmäßig. Wenn stattdessen in eine Datei zu schreiben versucht, ersetze ich den wprintf_s Anruf mit diesem (FILE *f zuerst natürlich erklärt hat):

if(_wfopen_s(&f, L"C:\\test.txt", L"w")) 
{ 
    fwprintf_s(f, L"%s\n", path) 
    fclose(f); 
} 

Allerdings habe ich auch versucht, fwrite sowohl mit w und wb-Modus verwenden, aber alle Methoden ergibt eine leere Datei.

+0

Try '_setmode (_fileno (stdout), _O_U16TEXT);' http://stackoverflow.com/a/36527398/4603670 –

+0

@BarmakShemirani Huh. Das funktioniert für stdout, aber ich bekomme immer noch leere Ausgabe für tatsächliche Dateien? Irgendwelche Ideen? – user966939

+0

Das Problem ist, dass die Terminal-Anwendung oder die App, die die Ausgabe zeigt, wahrscheinlich nicht richtig konfiguriert ist. –

Antwort

2

Sie benötigen _O_U16TEXT für die Konsolenausgabe und "UTF-16LE" für die Dateiausgabe.

Auch _wfopen_s Null zurückgibt, wenn erfolgreich MS nach documentation:

Rückgabewert Null, wenn erfolgreich; ein Fehlercode bei einem Fehler. Weitere Informationen zu diesen Fehlercodes finden Sie unter Fehlernummern, _doserrno, _sys_errlist und _sys_nerr.

Sie sollten sicherstellen Rückgabewert machen Null

if (0 == _wfopen_s(&f, filename, L"w, ccs=UTF-16LE")){ 
    //isokay ... 
} 

oder überprüfen, ob f Nicht-NULL ist. Zum Beispiel:

#include <stdio.h> 
#include <io.h> //for _setmode 
#include <fcntl.h> //for _O_U16TEXT 

int main() 
{ 
    _setmode(_fileno(stdout), _O_U16TEXT); 
    const wchar_t *buf = L"ελληνική"; 
    wprintf(L"%s\n", buf); 

    FILE *f = NULL; 
    _wfopen_s(&f, L"C:\\test\\test.txt", L"w, ccs=UTF-16LE"); 
    if (f) 
    { 
     fwprintf_s(f, L"%s\n", buf); 
     fclose(f); 
    } 

    return 0; 
} 
+0

Das hat es geschafft! Wie für das Überprüfen der Handle, nahm ich an, dass, da '_wfopen_s 'nicht Null bei Fehlern zurückgibt (wie fehlgeschlagen, ein Handle zu erstellen?), Würde es ausreichen, um das zu überprüfen ... Es ist mehr oder weniger wie sie es in der tun MSDN-Beispielcode mindestens (nur sie weisen den Fehler einer Variablen zu). – user966939

+2

@ user966939: Der Tooltip für den Upvote-Pfeil liest * "Diese Antwort ist nützlich" *. Es kommt mir immer merkwürdig vor, wenn jemand eine Antwort akzeptiert, ohne auch darüber abzustimmen. – IInspectable

+0

@Intspectable Nun, ich habe gerade bemerkt, dass er seine Antwort aktualisiert hat. Ich erkannte nun (obwohl ich in meinem vorherigen Kommentar auf den Rückgabewert von '_wfopen_s' selbst Bezug genommen hatte), dass ich nach Erfolg gegen eine NULL-Nummer im Code suchte, wenn der Erfolg tatsächlich 0 ist. Ich dachte, Barkak bezichtigte mich fälschlicherweise, Fehler gemacht zu haben, indem ich das Handle mit Hilfe des Rückgabewertes der Funktion überprüft habe. Natürlich verdient er auch einen Punkt. Ich glaube nicht, dass eine Sache notwendigerweise die andere impliziert. – user966939