システムを考えると、次のようなものが機能するはずです。
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main() {
setlocale(LC_CTYPE, "en_GB.UTF-8");
FILE * f = fopen("filename", "r");
wint_t c;
while((c = fgetwc(f)) != WEOF) {
wprintf(L"%lc\n", c);
}
}
元のコードの問題は、C が文字がマルチバイトであることを認識 (または気に) しないため、マルチバイト文字が\n
各バイトの間で破損することです。このバージョンでは、文字は UTF-8 として扱われるため、%lc
正しく出力されることが保証されている実際の 6 バイトを表すことができるようになりました。入力に ASCII が含まれる場合は、以前と同様に 1 文字あたり 1 バイトが使用されます (ASCII は UTF-8 と互換性があるため)。
strace
このようなもののデバッグには常に役立ちます。例として、ファイルに££
(£ には UTF-8 シーケンス \302\243 がある) だけが含まれているとします。あなたのバージョンは以下を生成します:
write(1, "\302\n\243\n\302\n\243\n\n\n", 10) = 10
私の物と、
write(1, "\302\243\n\302\243\n", 6) = 6
ストリーム ( を含むstdout
) の読み取りまたは書き込みを行うと、それはバイト方向またはワイド方向に設定され、変更する場合はストリームを再度開く必要があることに注意してください。たとえば、UTF-8 ファイルを読みたいが、stdout
バイト指向のままにしておく場合は、次のように置き換えることができますwprintf
。
printf("%lc\n", c);
これには、(フォーマットを変換するための) バックグラウンドでの余分なコードが含まれますが、バイト ストリームを予期する他のコードとの互換性が向上します。