Cのテキストファイルからの読み込み

本当に小さな質問です。 X個の単語を含むテキストファイルを読み込み、各単語をリンクリストに1つずつ追加するのに最適なのは何でしょうか。すなわちThe Frog Is Old。

したがって、The、Frog、Is、OldはそれぞれListNodeに入れられ、すべてファイルから読み込まれます。

fscanfが最適なオプションであっても、fscanfと組み合わせて使うのに最高の機能が本当に不思議です。すべてのアドバイスは素晴らしいです!

乾杯。

編集: 私の質問は本当に、大きなテキストファイルを解析したいのであれば、各単語を1つずつ配列に追加し、リストに追加し、配列を自由にし、繰り返すのが一番良いでしょうか?または、より効果的な方法がありますか?

1
リスト追加機能はデータのコピーを作成するのか、それとも直接所有するのか(オーナーシップを取る)? 意味のあるユーザー名を選ぶことを検討してください。これの利点の1つは、他の人が返信を使うことができ、誰かがあなたのコメントにあなたを対処したという通知。
追加された 著者 outis,
fscanfを使用しようとしましたか?もしそうなら、あなたは何か問題に遭遇しましたか?
追加された 著者 aleph_null,
strtokは文字列を解析することでmallocingを回避します。ただし、scanfを使用する場合は、 "%s" ではなく "%20s" という最大バッファ長を指定してください。
追加された 著者 aleph_null,
私の質問は本当に、大きなテキストファイルを解析したいのであれば、各単語を1つずつ配列に追加し、リストに追加し、配列を自由にし、繰り返すのが一番良いでしょうか?または、より効果的な方法がありますか?
追加された 著者 PnP,

3 答え

"%s"変換指定子は、空白以外の文字と一致します。

#define QUOTE(s) #s
#define STR(s) QUOTE(s)

#ifndef BUFSIZE
#  define BUFSIZE 255
#endif

char buf[BUFSIZE+1];
while (fscanf(fin, "%" STR(BUFSIZE) "s", buf)) {
    /* buf holds next word. Todo:
       + allocate space for word
       + copy word to newly allocated space
       + add to linked list
     */
}

また、 strtok をトークン化することもできます指定した文字セット(文字配列)を使用して、文字列を部分文字列に分割(分割)します。システムに strtp を置き換えることを意図した strsep もあります。 strtok strsep の両方で渡す配列を変更するので、データにアクセスするコードの他の部分に問題が発生しないように注意してください。 strsep はスレッドセーフではありません。パースする文字列に複数のスレッドがアクセスしている場合は、 strsep または strtok_r を使用します。

#ifndef BUFSIZE
#  define BUFSIZE 256
#endif

const char separators[] = "\t\n\v\r\f !\"#$%&'()*+,-./:;<=>[email protected][\\]^`{|}~";
char buf[BUFSIZE], *line, *word, *rest;

while (fgets(buf, BUFSIZE+1, fin)) {
    rest = line = buf;
    while ((word = strtok_r(line, separators, &rest))) {
        /* Todo:
           + allocate space for word
           + copy word to newly allocated space
           + add to linked list
        */
        line=rest;
    }
}

2番目の例は、 strtok_r のファイルから行を読み込んで、ファイルの行のいずれかがBUFSIZE-1文字を超え、BUFSIZE-1 st <行内のBUFSIZE th 文字は両方とも文字であり、2番目の例は2つの単語を分割します。これを解決するには、バッファリングされた文字列ストリームを作成し、バッファの終わりに達するとバッファに残っているものがすべて先頭に移動し、バッファの残りの部分がファイルのより多くのデータで満たされるようにしますバッファより長い単語には注意してください;プロダクションコードでは、サービス拒否攻撃につながる潜在的なセキュリティ上の脆弱性です。

上記のすべての関数の問題は、入力にヌル文字を処理しないことです。ヌル文字を含む可能性のあるデータを解析する場合は、独自の関数を含む非標準関数を使用する必要があります。

効率に関しては、使用するアルゴリズムはどれも複雑でO(n)であり、I/Oが必要でプログラムを遅くする必要があります。 fscanf strtok などの方法を使用する場合でも、時間と空間の複雑さはあまり変わらないでしょう。いくつの中間バッファが割り当てられるかについての唯一のことです。最も効率的な実装を見つけるための最良の方法は、カップルを試してプロファイルすることです。

3
追加された
1つ以上の事実、説教が少ない(私は私のことを書いている間あなたのことを見ませんでした。)
追加された 著者 luser droog,

「効率的ではない方法」を見つけるまで、「より効率的な方法」を探してはいけません。

しかし、 strtok のようなものは、 malloc せずにあなたのニーズに合っているかもしれません。 その場で文字列を刻むことができます。 (注意して使用!)

1
追加された

あなたが現代のデスクトップコンピュータで高速を探しているなら...あなたはマルチスレッドに行くことができます。

  • 1つのスレッドは、文字のバッファ、たとえば4Koを埋め込み、これだけを行います。
  • あるスレッドがバッファを読み込み、単語を解析してリストに追加します。
  • 1つのスレッドは、リスト全体を必要としない場合は、リスト上で何をしたいかを行います。

アイデアは、プロセスがI/Oを待つ間スリープしないということです。あなたがCPUコアをたくさん持っているならば、速度を上げるために、大きなチャンクでファイルをカットし、1つのコアプロセスが1つのチャンクをカットすることです。複雑なコードやバグの機会がたくさんありますが、ちょっと、スピードは安いわけではありません...

1
追加された