2017-06-28 11 views
0

テキスト(ASCII +ユニコード)を含むファイルがあり、C++プログラムを使用してその中の総単語数をカウントしようとしています。私がファイルを行ごとに(getlineを使用して)読み、その中の単語を数えるために各行を処理する必要があります。C++:ユニコード空白文字の解釈

は、だから私は、次の簡単なプログラム書かれている:

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 

int main(int argc, char* argv[]) { 
    uint64_t ct = 0; 
    std::string line; 
    std::ifstream infile(argv[1]); 
    while(std::getline(infile, line)) { 
    std::stringstream inputStream(line); 
    std::string token; 
    while (inputStream >> token) { 
     ++ct; 
    } 
    } 

    std::cout << ct << std::endl; 

    return 0; 
} 

をしかし、上記のプログラムはwc -wコマンドが与えるものよりも小さいです番号を出力します。問題を絞り込むために、プログラムを変更して、読み込んだものを単純に出力するようにしました。プログラムは次のようになります:

int main(int argc, char* argv[]) { 
    uint64_t ct = 0; 
    std::string line; 
    std::ifstream infile(argv[1]); 
    while(std::getline(infile, line)) { 
    std::stringstream inputStream(line); 
    std::string token; 
    while (inputStream >> token) { 
     std::cout << token << " "; 
    } 
    std::cout << std::endl; 
    } 

    return 0; 
} 

このプログラムの出力を別のファイルにリダイレクトしました。この新しいファイルでwc -wを実行すると、番号は元のファイルのwc -wと同じになります。つまり、自分のプログラムですべての単語(つまり、wcで定義されている「単語」)を読み込んでいます。したがって、を使用して読み取られるtokenの値の1つが、wcプログラムによって空白として解釈されるいくつかのユニコード文字で構成されていることが合理的な説明となります。どうすれば私のプログラムを変更して、ユニコードの空白文字のそのような解釈をサポートすることができますか?

+1

にvant。 Boostはこれをルックアップテーブルとして実装し、各文字を特定の型にマップし、ヒューリスティックスで型をチェックします。基本的には、BoostやQtのようなまともなUnicodeサポートが必要か、気にしないでください。 http://www.boost.org/doc/libs/1_62_0/boost/spirit/home/support/char_encoding/unicode。hpp –

+0

興味のある場合は、UnicodeテキストをUTF-32(開始バイトか継続バイトかプレーンASCIIかを確認する)に変換し、コードポイントを調べて、参照を使用して空白かどうかを確認しますテーブルを作成し、それをトークンとして使用します。 これが関係していると思いますが、それは大変な作業です。ブーストは特に顕著です。 –

+2

Unicodeにはかなりのスペース文字があります - これは文字とルックアップのマップになります。エラーが発生する可能性があるすべての楽しみに対してテストする必要があるため。高レベルから、C++はこのような文字列操作のための最良の言語ではないかもしれないと私は言います。 –

答えて

2

んが、有効なplain textファイルが両方のASCII &ユニコード[ED含まれていません:最低の128個のコード・ポイントに制限されているUTF-8でエンコードされたファイル以外の - /伝統的にとにかくASCIIと考えられていたさ - しかし、Unicodeはいくつかの可能な意味をエンコーディング];どちらか一方が含まれます。 Unicodeは混乱する可能性があります。しかし、それは本当に簡単です。 Unicodeは、ある「コードポイント」値にマップされた(巨大な)グリフ(図面)のセットです。それは、あらゆる言語(西洋のラテン語だけでなく)のすべてのASCIIのようなもので、ユニークな値に結合されてマッピングされています(文字の[uni versal [code] point)値にすべて同意できます)。

ASCIIは、人気のある初期の標準/慣習の1つに過ぎませんでした。 Unicodeは効果的にASCIIのスーパーセットです。 Unicodeはエンコード自体ではありません。 UTF-8はエンコーディング(バイト単位でもASCIIにマッチします)です。 Unicodeは答えで、UTF-8はバイトのパッケージ化です(UTF-8は最初の128文字のASCIIのパッケージ化にマッチします;外部の文字が使用されていない場合は100%いくつかの麻雀のタイルや他の点では見えない出力を気にしてください)

このトリックは、UTF-8に非常に忠実で、ASCIIと非常によく似ています。あなたのコードの入力&出力関数呼び出し

よだれかけ:。 http://utf8everywhere.org/

[編集:といくつかのリンクよりRELE外部依存することなく、簡単なことではないだろう、あなたの実際の質問]
https://www.cs.tut.fi/~jkorpela/chars/spaces.html
https://en.wikipedia.org/wiki/Whitespace_character

+0

私の最初の文章は技術的に間違っています。なぜなら、純粋なASCIIファイルは技術的に有効なUTF-8 Unicodeファイルであり、BOMがなくなってしまっているからです。 – veganaiZe

+0

私はあなたの意見に同意します。 BOMは必要ありません。 UTF-8でエンコードされたテキストファイルは、何も追加しないので、これらのファイルは使用することをお勧めしません。彼らは推測に役立ちます。推測は最初のポイントに戻る:ASCIIファイルには明確な違いがある。特定のエンコーディングを持つ128の特定の文字のいくつかをASCIIファイルに意図的に書き出しました。 UTF-8には、136755個の特定の文字と別の特定のエンコーディングのうちのいくつかが書かれていました。ファイルを読み込むことができるコンテンツの1つをサンプリングするのは無関係です。それは、書かれたエンコーディングで読むべきです。 –

+0

@TomBlodget BOMの使用はお勧めしませんでした。私は完全性のためにそれらを言いました。したがって、ASCIIテキストファイルも有効なUTF-8エンコードファイルであるという事実を否定する方法はわかりません。 – veganaiZe

関連する問題