4
FILE * f = fopen("filename", "r");
int c;

while((c = fgetc(f)) != EOF) {
    printf("%c\n", c);
}

こんにちは、私は 1 時間検索しましたが、Unicode に関する多くの賢明な論文を見つけましたが、この単純な質問に対する答えはありません。

gcc と bash を使用して Linux で UTF8 を管理できる、これらの 4 行に相当する最短のものは何でしょうか。

ありがとうございました

4

1 に答える 1

6

システムを考えると、次のようなものが機能するはずです。

#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);

これには、(フォーマットを変換するための) バックグラウンドでの余分なコードが含まれますが、バイト ストリームを予期する他のコードとの互換性が向上します。

于 2013-03-16T17:15:42.777 に答える