2017-01-12 2 views
2

Mein WinAPI-Programm zielt darauf ab, Text von einem Edit control zu nehmen und es in einer Datei zu speichern.fwprintf setzt Carriage-Return vor dem Zeilenvorschub

Wenn fopen die Datei im Textmodus "w" schafft, dann macht fprintf Zeilenvorschub LF Zeichen durch einen Wagenrücklauf CR vorangestellt werden.

HWND hEdit = CreateWindowA("Edit", NULL, WS_CHILD|ES_MULTILINE, 0, 0, 100, 100, 
          hWnd, (HMENU)ID_EDITORE, GetModuleHandle(NULL), NULL); 
// Input in Edit control a single line break "\r\n" 
int num = GetWindowTextLength(hEdit); 
char buffer[num+1]; 
GetWindowText(hEdit, buffer, num+1); 
FILE* file = fopen("test.txt", "w"); 
fprintf(file, "%s", buffer); 

Above Code schreibt nicht CRLF in der Datei, aber:

CRCRLF (0D 0D 0A)

Ich weiß, hier in der ANSI-Version der Lösung ist es, die Datei im Binärmodus zu öffnen: "wb" anstelle von "w", das macht keine CRLF Übersetzung oder Zeichenumwandlung findet während der Ausgabe statt.

Aber ich möchte Unicode-Zeichen in Edit-Steuerelement eingeben, und die Datei UTF-8 mit BOM codiert.
Was ist also mit den Wide-Character-Versionen _wfopen und fwprintf?

HWND hEdit = CreateWindowW(L"Edit", ...); 
// Input in Edit control a single line break "\r\n" 
int num = GetWindowTextLength(hEdit); 
wchar_t buffer[num+1]; 
GetWindowTextW(hEdit, buffer, num+1); 
FILE* file = _wfopen(L"test.txt", L"w,ccs=UTF-8"); 
fwprintf(file, L"%s", buffer); 

Above-Code nicht CRLF in die Datei schreiben, aber:

CRCRLF (EF BB BF 0D 0D 0A)

Keine Möglichkeit, diezu verwendenbinärer Modus, um die CR Addition zu vermeiden.

FILE* file = _wfopen(L"test.txt", L"wb,ccs=UTF-8"); 

Schreibt in der Datei des erwarteten \r\n aber codierte UTF-16, ohne BOM:

CRNULLFNUL (0D 00 0A 00)

Wie vermeiden Sie diesen CR Verbreitung für eine UTF-8-Datei?
Bin ich gezwungen, es UTF-16 zu kodieren?

Danke für jeden Vorschlag.

+0

Ich glaube wirklich, dass Wide-Character-Versionen der I/O-Funktionen nichts über UTF-8 wissen.Das ist keine "breite" Kodierung, es ist eine variable Breite. – unwind

+0

Um "" b "" und "" zu verwenden oder nicht, hängt von einem nicht erklärten Codierungsziel ab: Wollen Sie Dateien exakt gleich ausdrucken, auch wenn Code auf verschiedenen Plattformen kompiliert wurde (Benutzen Sie "b" und) die Zeilenendung der Wahl '" \ r \ n "' oder '" \ n "')? Oder möchten Sie, dass die Zeilenendung dem Inhalt des Compilers entspricht. (Verwenden Sie nicht "b" und "\ r" '). Was willst du _across_ Plattformen? Dies ist wirklich ein Compiler-Abschnitt, keine OS-Auswahl. – chux

+0

@unwind: '_wfopen' und' fwprintf' verwalten UTF-8 perfekt, dank dem Flag '" ccs = UTF-8 "' fügen sie die 'ï» ¿'BOM hinzu und machen alle Zeichen bei einer breiten Zeicheneingabe um. Der einzige Fehler besteht darin, [jeden Zeilenvorschub während der Ausgabe in eine Wagenrücklauf/Zeilenvorschub-Kombination zu übersetzen] (https://msdn.microsoft.com/en-us/library/aa273067.aspx). – Salvador

Antwort

1

Wie vorgeschlagen, ist eine mögliche Lösung, entfernen Sie alle CR s vor dem Schreiben buffer in Datei.
Dann fwprintf kümmert sich um eine CR vor jeder LF die Wiederherstellung der Paare \r\n.

HWND hEdit = CreateWindowW(L"Edit", ...); 
int num = GetWindowTextLength(hEdit); 
wchar_t buffer[num+1]; 
GetWindowTextW(hEdit, buffer, num+1); 

for(int i=0, id=0; id<=num; i++, id++) { 
    while(buffer[id]=='\r') 
     id++; 
    buffer[i] = buffer[id]; 
} 

FILE* file = fopen("test.txt", "w,ccs=UTF-8");  
fwprintf(file, L"%s", buffer); 
fclose(file); 
Verwandte Themen