- ベストアンサー
エラーの解消方法は?
- エラーがどうしても解消しません。コーディング無視、コメント無しです。
- 使用環境はXP-sp2 CPAT for Boland C++ Compiler Ver2.31 Boland C++ Compiler5.5 複数のテキストファイルを一つのファイルにまとめるプログラムです。33行目以降は出力です。読込48ファイル目でエラーが出てしまいます。
- 解決方法はあるのでしょうか。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
OSには「同時にファイルを開ける数」に上限があります。 この上限には「すべてのプログラムを通した全部の合計」と「1つのプログラムでの合計」など、色々あります。 また、Cコンパイラの場合、fopenの実装によっては「ファイルポインタは、内部的な、有限個の配列の、1つの要素を返す」と言う実装をしている場合があるのです。 つまり、内部的に FOPEN_MAX=50 FILE ___file_table[FOPEN_MAX]; みたいな感じで有限個の配列があって、配列の要素の個数がFOPEN_MAX個しかないのです。 で、stdinは___file_table[0]のポインタを差し、stdoutは___file_table[1]のポインタを差し、stderrは___file_table[2]のポインタを差していて、最初に3つ使用済みになっています。 そして、fopenが呼ばれるたびに、___file_table[3]、___file_table[4]のポインタが順に返されます(もちろん、クローズされて未使用になれば、またそれが再利用されて返されますが) で、この配列がクローズされずに全部埋まっちゃうか、オープン数が1プログラムの上限を越えるか、OSの上限を超えれば「もうダメぽ」って感じでエラーが出て止まります。
その他の回答 (3)
- chie65536
- ベストアンサー率41% (2512/6032)
因みに。 Windowsの前身のMS-DOSでは、コンベンショナルメモリを増やす方法として、CONFIG.SYSファイルに「同時オープン数の上限」が記述出来ます。 例えば FILES=16 とか。 MS-DOSの起動ドライブのCONFIG.SYSに上記のように書いておくと、同時に開けるファイルが16個だけになります。 そのような環境では、質問者さんのプログラムは、もっと早い段階でエラーで止まります。 なので「ファイルを開いて使い終わったら、使いもしないのに開きっぱなしで放置」したりしてはいけません。 複数のファイルを1つにするプログラムを書く場合は、 1.出力ファイルを開く 2.1つ目の入力ファイルを開く 3.中身を読み書きしてコピー 4.1つ目の入力ファイルを閉じる 5.2つ目の入力ファイルを開く 6.中身を読み書きしてコピー 7.2つ目の入力ファイルを閉じる 8.3つ目の入力ファイルを開く 9.中身を読み書きしてコピー 10.3つ目の入力ファイルを閉じる 11.出力ファイルを閉じる のような書き方をしましょう。 そうすれば FILE *ifp,*ofp; の2つのファイルポインタさえあれば処理できます。
お礼
丁寧に書いて頂ありがとうございます。 大変参考になりました。 今回、質問投稿は初めてなのでポイントの付け方が分かりません。 皆様にと思うのですが、ごめんなさい。
- sakusaker7
- ベストアンサー率62% (800/1280)
ひょっとしてファイルオープンに失敗するというエラーですか? 条件(OSとかそのへん)によって違いはありますが、 開きっぱなしにできるファイルの数には制限があります。 質問にあるコードではクローズをどのタイミングでやっているのかわかりませんが、 >7: FILE *fp[99],*fpo; というのをみるに、一辺にオープンして最後にまとめてクローズしようとしてませんか?
補足
回答ありがとうございます。 ファイルのオープンに失敗します。 一旦、50のファイルをオープンしてから、32行目以降にてfor文でfname1にオープンしたファイルの内容をコピーして*fp[99]を閉じてます。
- hidebun
- ベストアンサー率50% (92/181)
stdio.hの中に、FOPEN_MAXという値が定義されています。 これが50になっているのでしょう。 stdin, stdout, stderrがプログラム開始時に3ファイル分使用されて しまうので、50-3=47個が、同時に開くことが可能な最大数になります。 この値を変更する方法があるかもしれませんが、それよりもロジックを 見直したほうが良いでしょう。
お礼
早速の回答ありがとうございます。 stdio.h の中身がその様になっていたとは思っておりませんでした。 ロジックの見直しをがんばってやってみたいと思います。 関数も余り知らないので、知っている関数を使って一生懸命考えたあげく出たものです。 ありがとうございました。
お礼
回答ありがとうございます。 みなさんの回答内容が一緒なので、*fpはオープンして使ったらクローズするを心がけて、作り直したいと思います。