1

コマンド ライン引数として指定されたテキスト ファイルを開き、単語数、アルファベット以外の単語数 (例: 1998、2-3 など) をカウントする単純な単語カウント プログラムを実装したいと考えています。 on) そのテキスト ファイル内の文と段落。2 つのスペース間の文字配列が単語としてカウントされ、アルファベット以外の単語が数字、ハイフンなどで構成されると仮定します。各文は「.」で終了します。(ドット) 文字ですが、段落は改行で区切られます。次のように、各段落の単語数、アルファベット以外の単語数、文数、および開始行を保持する構造を使用します。

    struct {
      int word;
      int sentence;
      int nonAlpha;
      int startingLine;
      struct Paragraph*next;       
    }Paragraph; 

これにはリンクされたリストを使用することにしました。それで、使用される段落の数を反復して学習し、リンクされたリストを初期化し、それらをリンクし、またはファイルから読み取られた新しい段落があり、構造に格納する必要がある場合は、割り当てを続ける必要がありますか?

    Paragraph->next=(struct Paragraph*) calloc(1,sizeof(struct Paragraph));

ご協力ありがとうございました。

4

4 に答える 4

2

SIZEを指定せずに動的に割り当てるにはどうすればよいですか?

サイズを知らずに連続した配列を割り当てることはできません。

私はあなたにいくつかのオプションを与えます:

  1. を使用して大きなサイズのチャンクに事前に割り当て、mallocそこにコピーします。ファイルreallocの読み取り中にサイズが不足した場合は、より大きなサイズのチャンク。

  2. 最初にファイル内の単語数をその数だけ数え、malloc次にファイルを再度読み取ります。

  3. リンクリスト構造を使用します。malloc単語ごとに、次へのポインタがあります。

于 2012-12-12T22:13:53.573 に答える
1
struct Paragraph *dynamicParagraph = malloc(SIZE * sizeof(Paragraph));

また、C/C++ では配列とポインターは基本的に同じものであるため、配列として使用できます。

Paragraph specificParagraph = dynamicParagraph[index]; //Assuming index < SIZE and > 0
于 2012-12-12T22:10:54.310 に答える
0

説明に基づいて、struct段落ごとに 1 つのインスタンスが必要です。したがって、改行文字に遭遇するたびに、新しい段落カウントを開始する必要があります。

オブジェクトの初期数を動的に割り当てることから始めてParagraph(ほとんどの場合をカバーするのに十分です)、必要に応じてそのブロックを拡張します。

#define INITIAL_SIZE ... // some initial value, say 5 or 10
...
size_t numParas = 0;     // keep track of the array size
size_t parasRead = 0;    // keep track of the paragraphs read
...
struct Paragraph *paras = malloc(sizeof *paras * INITIAL_SIZE);
if (paras)
{
  numParas = INITIAL_SIZE;
}
else
{
   perror("Could not allocate initial memory...exiting");
   exit(-1);
}

... // open the file and read input

while (more_data)
{
  int c = fgetc(input);

  // update the various fields of paras[parasRead]
  // based on the value of current_character

  if (c == '\n')
  {
    // ready to start a new paragraph.  If we've reached the end
    // of the paras array and don't have a new slot available,
    // extend the array by doubling its size
    if (parasRead + 1 == numParas)
    {
      struct Paragraph *tmp = realloc(paras, sizeof *paras * (numParas * 2));
      if (tmp)
      {
        paras = tmp;
        numParas *= 2;
      }
      else
      {
        perror("Could not extend the paras array...exiting");
        free(paras);
        exit(-1);
      }
    }
    parasRead++;
    moreData = (c != EOF);
  }
}

// display results
...
free(paras);

これで少なくとも始められるはずです。reallocバッファを拡張できない場合の対処方法を決定する必要があります。上記のコード例では、これを致命的なエラーとして扱い、すぐに終了しますが、バッファーを少しだけ拡張することもできます (2 倍にする代わりに、1.5 倍に増やし、失敗した場合は 1.25 倍にするなど)。 . ループを終了して、得られた結果を提示することができます。または、まったく異なるもの。

これを整理するためのより良い方法もおそらくあります。配列管理コードを別の関数に分離することをお勧めします。しかし、これで何が必要かを理解できるはずです。

于 2012-12-12T22:57:24.540 に答える