2009-09-03 6 views
18

Cで単純なテキストファイルを読み込んで1行ずつ出力する小さなアプリケーションを作成しています。問題は、テキストファイルにÆ、Ø、Åなどの特殊文字が含まれていることです。ターミナルでプログラムを実行すると、それらの文字の出力は "?"で表されます。C(UTF-8エンコーディング)での特殊文字の扱い

簡単な修正はありますか?

答えて

28

まず物事:

  1. 読むバッファ内
  2. 使用したlibiconvまたはUTF-8からのwchar_tタイプを取得して、そのようなwprintf()
  3. 使用などの機能を扱うワイド文字を使用するのと同様のCでのワイド文字の関数ほとんどのファイル/出力処理関数にはワイド文字のバリアントがあります

端末がUTF-8出力を処理できることを確認してください。正しいロケールの設定とロケールデータの操作は、あなたが行っていることに応じて、ファイルのオープンと変換の多くを自動化することができます。

は、UTF-8のコードポイントまたは文字の幅が可変であることを覚えておいてください。つまり、コードポイントの真ん中に着陸する可能性があるので、単にバイトを探してASCIIのように読み始めることはできません。良いライブラリは場合によってはこれを行うことができます。ここで

はCでの取り扱いUTF-8のファイルの読み取りとワイド文字のいくつかの使用法を示し、いくつかのコード(ではない私のもの)である

#include <stdio.h> 
#include <wchar.h> 
int main() 
{ 
    FILE *f = fopen("data.txt", "r, ccs=UTF-8"); 
    if (!f) 
     return 1; 

    for (wint_t c; (c = fgetwc(f)) != WEOF;) 
     printf("%04X\n", c); 

    fclose(f); 
    return 0; 
} 

リンク

  1. libiconv
  2. Locale data in C/GNU libc
  3. Some handy info
  4. Another good Unicode/UTF-8 in C resource
+0

ありがとう!私はこれを試してみます... – o01

+0

問題はありません。 C言語のUnicodeは、世界でもっともシンプルなものではありません。標準にも慣れてください:) –

3

誤ってバイトを削除していないことを確認してください。いくつかのUTF-8文字は1バイト以上の長さです(これは一種のポイントです)、それらをすべて保持する必要があります。

六角としてバッファの内容を印刷することが有用であることができますので、あなたが実際に読み込まれたバイト調べることができます。

static void print_buffer(const char *buffer, size_t length) 
{ 
    size_t i; 

    for(i = 0; i < length; i++) 
    printf("%02x ", (unsigned int) buffer[i]); 
    putchar('\n'); 
} 

あなたはわずか数を含む、非常に短いファイルをロードした後、これを行うことができます文字。

端末が適切なエンコーディングに設定されていることも確認してください。そうすれば、文字はUTF-8として解釈されます。最初

+0

端末はUTF-8エンコーディングに設定されています。プログラムは、fgets()を介してテキストファイルの各行のすべての文字をchar配列に格納します。私がバイトを失っているなら、それをどうやって修正するのか分かりません。(ちょうどCのbtwを学び始めて) – o01

+0

@Eirik、fgets()はASCIIを使ってはいけません。私の投稿からfgetwc()を使用してください。 –

2

おそらくあなたのテキストファイルは、ISO-8559-1でエンコードされますが、あなたの端末がUTF-8です。この種の不一致は、バイト指向のテキスト処理を扱う際の標準的な問題です。他のCプログラム(標準の 'cat'や 'more'コマンドなど)は同じことを行い、一般的には修正する必要のあるエラーや何かとはみなされません。

バイトの代わりにUnicode文字レベルで操作したいが、プログラム全体で文字の代わりに文字型としてwcharを使用する必要があり、ユーザーが入力ファイルのエンコーディングは実際にはです。 (時々推測することができますが、あまり信頼性がありません)

2

端末と入力ファイルのエンコーディングが同じであることが確かであれば、それは役に立ちますか? setlocale()

#include <locale.h> 
… 
setlocale(LC_CTYPE, ""); 
+0

'setlocale(LC_CTYPE、" UTF-8 ");'を使用しました。シェル環境が適切に構成されていても、ファイルを正常に読み取る必要がありました。 – lkuty

+0

'setlocale(LC_CTYPE、") 'で、変更すべきロケールの各部分は、環境変数に従って設定されます。 – jgrocha

+0

ああ、申し訳ありません、それは '' ''で、 '' NULLではありませんでした。 –

関連する問題