• ベストアンサー

配列のメモリの確保

先日メモリについてご質問させていただいたものですが、 今ファイルから読み込んだ文字列を配列に格納する作業を行なっています。 今は char buf[1000]; FILE fp; if((fp=fopen("○○.txt","r")) ==NULL){ printf("ファイルが開けません"); } while(fgets(buf,1000,fp) != NULL){ としてファイルを一行ずつ読み込んでその後単語ごとに配列に組み込みます このときファイルの文字列を格納する配列はbuf[1000]ですが このメモリでは足りないかもしれませんし多すぎるかもしれません。 足りない場合はエラーになるし多すぎる場合はメモリの無駄ですよね。 このような場合はメモリを取り直すべきなのでしょうか?その場合 どのような方法がありますか?調べてもint型の領域確保とかそういうのはあるんですがファイルから読み込んだ文字列の領域確保とかは見つからなかったので教えて下さい。

質問者が選んだベストアンサー

  • ベストアンサー
  • trapezium
  • ベストアンサー率62% (276/442)
回答No.3

いくつも方法はありますが、 簡単に処理するのであれば、fgets()したあと len = strlen(buf); if (len > 0 && buf[len - 1] != '\n') でエラーメッセージを表示して終了してしまうことです。 一行の長さ無制限としたいのであれば、単語の格納処理で'\n'が見つからなければ、その時点のbufへのポインタをptrとしたとき off = 0; while (fgets(buf + off, sizeof(buf) - off, fp) != NULL) { ...processing... off = strlen(ptr); if (off > 0 && ptr[off - 1] != '\n') strncpy(buf, ptr, --off); } などとしてbufに読み足す方法があります。この場合実際はfread()使う方が効率的だとも思います。

zaqwe
質問者

お礼

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

その他の回答 (2)

  • kot_o
  • ベストアンサー率16% (6/36)
回答No.2

通りすがりです。 256で十分ではないでしょうか。 文字列は、一行までしか記述出来なかったっというような話を聞いたことがあり、私は、ファイルロードの際は大抵、一行256文字で読み込んでいます。 厳密に調べた事はありませんし、ファイルの仕様によって違うかもしれません。 ですので、参考意見としてください。 ちなみに、様々なテキスト形式のファイルを読んだことがありましたが、256文字で問題はありませんでした。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.1

fgets()は改行文字が見つからなくてもエラーにはなりません。 「改行文字、EOF、バッファサイズ-1」の中で最も短く読むだけです。 また、標準では「一行全て読む」関数はありませんから、「必ず一行全部取れていないと都合が悪い」のであれば充分な大きさのバッファを確保しておくのが前提になります。 さもなければmallocとreallocを駆使して #define BLOCKSIZE 1024 int bufsize = BLOCKSIZE; char *buf = malloc(bufsize * sizeof(char)); char *read_ptr; FILE *fp; ... // この外でfpのEOF判定をしておく fgets(buf, bufsize, fp); while(strchr(buf, '\n') == NULL){ // 改行が見つかるまで繰り返す buf = realloc(buf, bufsize + BLOCKSIZE); read_ptr = buf + bufsize; bufsize += BLOCKSIZE; if(fgets(read_ptr, BLOCKSIZE, fp) == NULL) break; // 終端に来たら抜ける } ... // 最後の解放を忘れずに free(buf); こんな感じですか。エラー処理を方々端折ってますが。 これはBLOCKSIZE(1024)単位で一行に満たなかった場合にバッファを拡張しています。 なお縮小の方は考えていません、というかfgets()で行単位処理を行う時のバッファサイズは「予期される一行の最大文字数」に合わせておくのが鉄則です。

関連するQ&A

専門家に質問してみよう