- ベストアンサー
ファイルの結合
C言語にて、ファイルAのデータの後にファイルBをつなげる場合、 ファイルAを1行ずつ読み出してファイルCに書き込み、 続けてファイルBを1行ずつ読み出して、またファイルCに書き込む。 その後ファイルAを消してファイルCをファイルAとし置き換える。 といった方法でやるのでしょうか? また、fopenで追加書き出しのオプションaの場合も、結局は 上記と同じことをやっているのでしょうか? ご存知の方、教えてください。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
Aの後ろにBの内容を追加するだけで可能。 ただし、途中で異常終了した場合、Aの内容が破壊される可能性があるので、作業ファイルを使うこともありますが、あくまでも方法論です。 別にファイルを結合するのが目的であれば、バイナリモードで開いて読めるだけ読むのでもかまいません。 >また、fopenで追加書き出しのオプションaの場合も、結局は >上記と同じことをやっているのでしょうか? ということで、違います。 そんなことをしていたら、巨大なファイルをオープンしたら同じサイズのディスク容量が必要になってディスク容量不足に陥る可能性があります。
その他の回答 (7)
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>他サイトで教えていただいたコードです。 >こういう回答を期待してました。 はぁ、そうだったんですか・・・ 流れからだと、 >また、fopenで追加書き出しのオプションaの場合も、結局は >上記と同じことをやっているのでしょうか? 「aを使った場合、一時ファイルはいらないよ」という回答をしました。 >じゃあ、オプションaを使わない場合は、どんなコードで実現するのか、教えていただけたらうれしいのですが。 #あれ?それって一時ファイルを使う方法のことじゃないの?という思い。 >ファイルCを使わない方法を知りたいのですが。 「aを使えばできるよ」という回答をしました。 #なんで元に戻ってんだ?という思い。 まず、ここでずれてきちゃってますね。 #1と#2のお礼の内容を別々と考えずに、合わせて、 「モードaを使わずに、一時ファイルも使わない方法が知りたい」と思えばよかったのですが。 >別の言い方をすると、モード"a"と同じ機能のコードを知りたいということです。 ここですね。大きくずれたのは。 「モード"a"と同じ機能のコード」と書かれると、#4の方のような回答が出てきてしまいます。fopenを自分で作るような感じの回答です。 >4.じゃあ、勉強の為に知りたいのですが、fopenのモードaの関数はC言語でどのように記述されているのでしょうか? いくらなんでも、ここからは#7のお礼の内容は出てきません。 これはあくまでも、 「fopenのモードaを使わずに、一時ファイルも使わないでファイルの結合処理を行うソース」です。 fopenのC言語での記述ではないです。 ということで、私のほうも勘違いがありましたが、小出しに用件を書かれると、それがandなのか、ぜんぜん別件なのか判断できないこともあるので必要な情報ははしょらないで欠いてくださいね。 #r+のことを忘れて、途中回答を間違えてたってのもありますが・・・
お礼
いつも回答ありがとう御座います。 #どもども、とにかく今回のことは忘れてください。 こんなに貴殿と会話がかみ合わなかったのは初めてです。 いつもは、他の人とはかみ合わなくても、貴殿だけは豊富な知識に裏づけされているからだと思いますが、”ははぁ~んあれのことで悩んでるんだな。”と察して頂いて、ずばり的確な回答を頂いてたのですが。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>4.じゃあ、勉強の為に知りたいのですが、fopenのモードaの関数はC言語でどのように記述されているのでしょうか? ということでしたらある程度意味はわかりますが。 では、処理系は?Windowsですか?Linuxですか?コンパイラは何をお使いで? という話になります。 多くの開発環境は標準関数のソースが付属していますので基本的にはそちらを見てくださいというのが回答です。 それでは、そっけないので。 この質問ですと、どこまでの深さで?ということにもなります。 Cの標準関数というのは、基本的にプラットフォームの違いを埋めてくれているのでWindowsでもUnixでも同じように使えます。 ファイルIOのように、もろに処理系に依存している処理ですと、必ずOSまたはハード等を直接たたく処理が存在します。これがWindowsですとWindowsAPIにあたります。 ただし、fopenは高水準のファイルIOなので、低水準の標準C関数の組み合わせで実現可能です。 #実際のfopenのソースが標準関数のみでかかれているかは別問題です。 なので、情報としてはまだ不足しています。 ”別のC標準関数を使って”or”処理系依存の処理も使用して”ということが。
お礼
回答ありがとうございます。 他サイトで教えていただいたコードです。 こういう回答を期待してました。 #include <stdio.h> int main() { FILE* pf_a; FILE* pf_b; int c; pf_a = fopen( "a.txt", "r+" ); fseek( pf_a, 0, SEEK_END ); pf_b = fopen( "b.txt", "r" ); for( c = getc( pf_b ); c != EOF; c = getc( pf_b ) ) putc( c, pf_a ); fclose( pf_b ); fclose( pf_a ); return 0; }
- somejun
- ベストアンサー率0% (0/1)
fopenのモード"a"を使わずに追加書き出しを実現ですか…。 モード"a"は読み込み&追加書き込みであることと、既存のファイルを壊さない上に、ファイルが存在しない場合には作成するという機能を持ってますから、似た様な機能を持つ"r+"と"w+"を適切に選択しないとファイルを開けませんね。 まずは、fopenで開く前に_stat関数でファイルの有無を調べておき、存在するなら"r+"で、存在しないなら"w+"でfopenしましょう。 それから、ファイルを開いたらファイルの終端にファイルポインタを移動して、終端に追加書き込みできる様にする必要がありますね。 fseek(fp,0,SEEK_END); ってな感じの処理が必要でしょう。 コード書くの面倒なので、ざっとおおまかな流れだけ書きましたけど、分かりますか?
お礼
回答ありがとうございます。 まったく問題無く理解できますよ。 あとは、この内容のコード書くのがどれだけ大変なのかがイメージできません。(ファイル入出力のオーソドックスなことしかやったことがないため) 便利な関数があるのに無理に自作する気はありませんが、勉強の為にそれほど難しくないのであれば教えていただきたいと思い質問しました。 もちろんコードの提示は不要です。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>>このアドバイスに従い、 >>ファイルCを使わない方法を知りたいのですが。 > >モード"a"を使わずに実現する方法がしりたいのですが。。。 > >別の言い方をすると、モード"a"と同じ機能のコードを知りたいということです。 うーん、#2のお礼の内容からは、どうやっても読み取れないんですが・・・ 一時ファイルを使わずに、fopenをa以外で使うのは無理でしょう。どう考えたって。aとrとwの動作を考えれば。 #まぁ、a+ってのがあるけど、aと同じだし。
お礼
>一時ファイルを使わずに、fopenをa以外で使うのは無理でしょう。どう考えたって。aとrとwの動作を考えれば。 う~ん、今回の質問だけはどうして意図が通じないのかこちらも困惑しています。 これまでの話は無かったことにして、もう一度質問します。 1.fopenのモードaは一時ファイルを使わない。 2.fopenのモードaの動作はC言語で書かれている。 (この前提が間違っていたら、この質問は成立しません) 3.巨大ファイルの存在を考えると、一時ファイルは使いたくない。 4.じゃあ、勉強の為に知りたいのですが、fopenのモードaの関数はC言語でどのように記述されているのでしょうか? ということなのですが。。。
- fruipa
- ベストアンサー率38% (14/36)
fopenのモードaが内部でやっているのは、もっと低レベル(機械言語に近い)なアクセスだと思います。 それに少し近づくのであればopenやlseekなどを使ってみてはいかがでしょうか?
お礼
そうですか。そう簡単なことではないということですね。 回答ありがとうございました。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>このアドバイスに従い、 >ファイルCを使わない方法を知りたいのですが。 ファイルAをモード"a"とか"ab"でオープンして、そこにbの内容を書き込むだけですけど。 何か問題ですか? 自分で試してください。
お礼
モード"a"を使わずに実現する方法がしりたいのですが。。。 別の言い方をすると、モード"a"と同じ機能のコードを知りたいということです。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>じゃあ、オプションaを使わない場合は、どんなコードで実現するのか、教えていただけたらうれしいのですが。 それって、 >ファイルAを1行ずつ読み出してファイルCに書き込み、 >続けてファイルBを1行ずつ読み出して、またファイルCに書き込む。 > >その後ファイルAを消してファイルCをファイルAとし置き換える。 これのことでは? これだとrとwしか使わないような。
お礼
回答ありがとう御座います。 >そんなことをしていたら、巨大なファイルをオープンしたら同じサイズのディスク容量が必要になってディスク容量不足に陥る可能性があります。 このアドバイスに従い、 ファイルCを使わない方法を知りたいのですが。
お礼
回答ありがとう御座います。 >Aの後ろにBの内容を追加するだけで可能。 そうなのですか。 じゃあ、オプションaを使わない場合は、どんなコードで実現するのか、教えていただけたらうれしいのですが。