- 締切済み
テキストファイルへ半永久的に出力し続けることは可能でしょうか。
こんにちは。いつもお世話になっております。 C言語で、半永久的に文字列をテキストファイルに出力し続ける、という事は可能でしょうか。要は、ファイルを無限に更新し続けるプログラムを書きたいと考えています。元のファイル(file.txt)の文字列を、形式を変えて、別のファイル(out.txt)に出力し続けたいのですがどうしても出力が止まってしまい上手くいきません。自分なりに以下のようなプログラムを作ってみました。何かアドバイスを頂けないでしょうか。 前提条件: ・別プログラムによりfile.txtは末尾に文章が追加され続けている ・本プログラムは半永久的に動き続ける #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<errno.h> #include<signal.h> #include<sys/types.h> int main () { int i = 0, j = 0, len; FILE *fp, *fp2; char buf[1024] = ""; char str[1024] = ""; while (1) { //ループ2周目以降なら一度クローズして開き直す if (i >= 1) { fclose (fp2); } if ((fp2 = fopen ("out.txt", "a")) == NULL) { printf ("out.txt:open error\n"); exit (-1); } //上と同じく if (i >= 1) { fclose (fp); } if ((fp = fopen ("file.txt", "r")) == NULL) { printf ("file.txt:open error\n"); exit (-1); } //既にout.txtに移した部分が重複しないようにfgetsで調整 if (i >= 1) { for (j = 0; j <= i; j++) { fgets (str, 1024, fp); } } //file.txtからout.txtに内容を移す while (1) { i++; if ((fgets (str, 1024, fp)) == NULL) break; if ((len = strlen (str)) >= 2) { str[len - 1] = '\0'; } else { break; } if (len <= 50) break; fprintf (fp2, "%s\n", str); } } return 0; } プログラムの内容は、 更新され続けるテキストファイル(file.txt)から、別のテキストファイル(out.txt)に出力するというプログラムです。(元となるfile.txtの内容を若干変えつつ、out.txtに出力することが本来の目的ですが、その部分は省略させて頂きました。) fopenで開くと、「その時点まで」のfile.txtしか開かれません。従って更新され続けているfile.txtの内容をコンスタントに読み取る為に、while文でfopenし続ける方法を取りました。しかし、out.txtを確認すると何故か一定の行からそれ以降が追記されないままでした。恐らく一度目のfopenにより開いたfile.txtの内容のみを抽出して、2度目以降のfopenによる読み取りが意味を為していないのではないかと推測しますが・・、どうなんでしょう。あまり自信はないです。 これを解決して半永久的に出力を続けるにはどうすればよいでしょうか。 上のプログラムや私の意図する所で何か気づかれた点や、おかしいと思われた点等ありましたら是非ご教授頂きたく思います。 どんな些細なことでも構いませんので、教えて頂けないでしょうか。 環境はCentosです。どうぞよろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- arain
- ベストアンサー率27% (292/1049)
OSやファイルシステムによる制限を除外したとして、 >半永久的に は有限である変数を使用している時点でその変数がオーバーフローすれば終わってしまう。 >何故か一定の行からそれ以降が追記されないままでした。 その「一定」も上記に関係している可能性もある。 根本的な問題として、 >更新され続けるテキストファイル(file.txt)から、別のテキストファイル(out.txt)に出力するというプログラムです。 おそらく、file.txtは別アプリで更新され続けるんだろうけど、明示的にファイルを排他制御していないと(ソースを見る限りその痕跡はない)、file.txtを出力するアプリ自体もファイルオープンエラーで引っ掛かかる気がするんだけど。 ファイルサイズが大きくなればなるほど、ファイルがロックされる時間が長くなるため、問題が顕在化しやすくなるけど大丈夫?
- Tacosan
- ベストアンサー率23% (3656/15482)
Centos というのがどんな OS なのかよくわかりませんが, CentOS なら QNo.4467942 の #4 にしたがうのが最も簡単でしょう. もちろん「簡単な道があることを知っていてあえて困難な道を歩む」ことを否定するわけではありません. ただ, 「あえて困難な道を歩む」なら他人に聞いたりせずすべて自助努力でなんとかしてほしい.
- noah7150
- ベストアンサー率46% (116/251)
//file.txtからout.txtに内容を移す while (1) { i++; if ((fgets (str, 1024, fp)) == NULL) break; if ((len = strlen (str)) >= 2) { str[len - 1] = '\0'; } else { break; } ファイル読めてないのにi++はおかしい if ((fgets (str, 1024, fp)) == NULL) break; i++; しっかり眺めた訳じゃないので・・・ 読込みのバッファはmemsetでフル0で埋めた方が良いのでは
- gonbee774
- ベストアンサー率38% (198/511)
ちょっとプログラミングの世界から離れているものですが… >fopenで開くと、「その時点まで」のfile.txtしか開かれません。 同様な問題を回避するため、APIを使ったことがあります。 CentOSは知らないのですが、私はWindowsでしたので、FileCreateで、『ファイルの共用』としました。 これにより、一度のOPEN(FileCreate)で済みました。 また、直接的な原因ではないと思いますが、2046バイトごとにiをインクリメントしていますが、半永久的に考えるなら、オーバーフロー(最大値を超える)を考慮する必要がある気がします。 あと、深く追っかけてないですが、 if (len <= 50) break; が何をされようとしているのが判りませんでした。 #そもそも環境によっては扱えるファイルの最大の大きさの制限があるかもしれませんが、そこは大丈夫ですよね?
- Yanch
- ベストアンサー率50% (114/225)
> //既にout.txtに移した部分が重複しないようにfgetsで調整 > if (i >= 1) > { > for (j = 0; j <= i; j++) > { > fgets(str, 1024, fp); > } > } 何行読み込むつもりなのですか?