1

質問があります。ご協力いただければ幸いです。

周波数分析を実行するファイルから文字を読み取ろうとしています。これを行う最も簡単な方法は、インデックス 0 ~ 255 を持つ配列を用意し、char が読み取られるたびに対応するインデックスを (読み取り chars 10 進値から) 1 ずつインクリメントすることであると判断しました。私が抱えている問題は、7 ビット文字のみが保存されているように見えることです。コードについては、以下を参照してください。

int frequency(FILE *freqfilep)
{    
    printf("frequency function called!\n");

    int start = 1;
    int *frqarray = calloc(256,sizeof(int));
    unsigned char tecken;

    FILE *fp;
    fp = fopen("freqfile.txt","r");

    if (fp == NULL) 
    {
        perror("Error in opening file");
        start = 0;
    }
    do
    {
        tecken = fgetc(fp);

        if (feof(fp))
        {
            start = 0;
        }
        else
        {
            frqarray[(int)tecken] ++;
        }
    }
    while (start != 0);

    printf("a%d\n", frqarray[97]);
    printf("b%d\n", frqarray[98]);
    printf("c%d\n", frqarray[99]);
    printf("1%d\n", frqarray[49]);
    printf("2%d\n", frqarray[50]);
    printf("3%d\n", frqarray[51]);
    printf("å%d\n", frqarray[134]);
    printf("ä%d\n", frqarray[132])
    printf("ö%d\n", frqarray[148]);

    fclose(fp);

    return 0;
}

私が読んでいるファイルには、次の文字が含まれています。

aaa bbb ccc 111 222 333 ååå äää ööö

したがって、コードの下部にあるprintfは次のようになります。

a3
b3
c3
13
23
33
å3
ä3
ö3

しかし、結果は

a3
b3
c3
13
23
33
å0
ä0
ö0

したがって、8ビット文字の読み取りに問題があると推測しています。フォーラムを少し調べたところ、このようなバッファを使用する必要があるという比較的似た投稿がいくつか見つかりましたがfread(&buffer, 256, 1, file);、それを実装する方法がわからない。

4

2 に答える 2

2

これらの文字は、ほとんどの場合、上位ビットが設定されたシングルバイト文字ではなく、マルチバイト文字です。

これらの文字は、次の UTF-8 コードポイントで表されます。

  • å: 0xc3 0xa5 (10 進数 195 165)

  • ä: 0xc3 0xa4 (10 進数 195 164)

  • ö: 0xc3 0xb6 (10 進数 195 182)

以下をコードに追加します。

printf("195 %d\n", frqarray[195]);
printf("165 %d\n", frqarray[165]);
printf("164 %d\n", frqarray[164]);
printf("182 %d\n", frqarray[182]);

そして、おそらく次の出力が得られます。

195 9
165 3
164 3
182 3

編集:

文字の頻度分析を行う必要がある場合はfgetwc、代わりに文字を読み込むために使用します。すべての文字が基本的な多言語セット ( Unicode文字 U-0000 - U-FFFF) にあると予想される場合は、サイズ 65536 の配列を作成して出力できます。その範囲を超える文字が予想される場合は、別のスキームを使用することをお勧めします。

于 2016-02-02T16:18:54.750 に答える
1

エンコードの問題が発生している可能性があります。これは、頻度表全体を印刷することで確認できます。予想していた一部の文字の出現が記録されていないことに加えて、予想していなかった一部の文字の出現が記録されていることに気付くでしょう。

これは、 C char、特にunsigned chars が基本的にバイトの表現であり、たとえばUnicodeの用語の意味での「文字」の表現ではないという事実に帰着します。読み込んでいるファイルがマルチバイト エンコーディングでエンコードされている場合 (UTF-8 である可能性が高い)、fgetc()そのエンコーディングの個々のバイトを読み取り、それらをコード ポイント値にデコードしません。さらに、C プログラムで内部的に使用されている文字エンコーディングがファイルのエンコーディングと同じであるとは限りません。

文字データを読みたい場合は、正しくデコードする必要があります。プログラム自体にデコード ロジックを記述したくない場合は、入力ファイルがプログラムの期待どおりにエンコードされていることを確認する必要があります。のようなトランスコーダiconvはそれを助けることができるかもしれませんが、ファイルの現在のエンコーディングと変換したいエンコーディングの両方を知る必要があります。

于 2016-02-02T16:25:49.660 に答える