No.15507![]() |
ファイルの指定行に文字列を書き出す方法 投稿者---ぜろ(2004/07/14 15:02:45) |
||
初めて質問致します。 よろしくお願い致します。 ファイルをオープンして、決められた行番号に文字列を格納する という処理を行いたいのです。 例えば、「5行目にりんごという文字列を書き出す」ためには、 どのようにしたらよいのでしょうか。 私は、改行が4個読み込めたら、そこにりんごと書き出す方法を 考えました。 しかし、4行読み込んでその後に書き込むことはできるのでしょうか。 やはり、文字列を配列に格納し、1回ファイルをクローズして、 またオープンして追加する?のような処理になるのでしょうか。 質問ばかりで申し訳ありません。 ぜひご助言を賜りたいです。 |
No.15522![]() |
Re:ファイルの指定行に文字列を書き出す方法 投稿者---ZAQ(2004/07/14 20:58:19) |
||
fseek を使ってみてはどうですか? |
No.15525![]() |
Re:ファイルの指定行に文字列を書き出す方法 投稿者---NykR(2004/07/14 22:18:13) |
||
>私は、改行が4個読み込めたら、そこにりんごと書き出す方法を >考えました。 >しかし、4行読み込んでその後に書き込むことはできるのでしょうか。 >やはり、文字列を配列に格納し、1回ファイルをクローズして、 >またオープンして追加する?のような処理になるのでしょうか。 ファイルをもう一つ、書き込みモードで開いてそっちに書き込んでから、元のファイルにrenameするのが簡単だと思います。 「もう一つのファイル」と同名のファイルがすでに存在していたら、上書きされてしまうので気をつけなければいけませんが。 そういう事態は、こういう関数を使うことである程度は防げるかも知れません。 #include <stdio.h> #define LOWER "abcdefghijklmnopqrstuvwxyz" char * getUniqueFile(char * dest, size_t size) { int i, j; FILE *fp; for (i = 0; i < size - 1; i++) { dest[i+1] = '\0'; for (j = 0; j < sizeof(LOWER) - 1; i++) { dest[i] = LOWER[j]; // 読みとりモードで開けなかったら // destに格納されている文字列と同名のファイルは存在しない(多分) if ((fp = fopen(dest, "r")) == NULL) { // ファイルをとりあえず作って、 // 次の呼び出し時に同じ名前を返すのを防ぐ fclose(fopen(dest, "w")); return dest; } fclose(fp); } } return NULL; } |
No.15543![]() |
Re:ファイルの指定行に文字列を書き出す方法 投稿者---ぜろ(2004/07/15 11:06:50) |
||
早速回答ありがとうございます。 fseek関数を使用する場合を考えてみました。 fseek関数は、ファイルポインタの参照位置をoriginで指定された位置を 基点にoffsetバイトの位置に移動させるということですが、バイトだと行 をかえることはできないのでは、と思いました。改行文字がある場合は、 offsetを1に指定するとファイルポインタの参照位置は次の行になるので しょうか。 回答して頂いたのに、その意味を理解できなくて申し訳ありません。 よろしくお願いいたします。 |
No.15545![]() |
Re:ファイルの指定行に文字列を書き出す方法 投稿者---REE(2004/07/15 13:11:18) |
||
>ファイルをオープンして、決められた行番号に文字列を格納する >という処理を行いたいのです。 >例えば、「5行目にりんごという文字列を書き出す」ためには、 >どのようにしたらよいのでしょうか。 >私は、改行が4個読み込めたら、そこにりんごと書き出す方法を >考えました。 >しかし、4行読み込んでその後に書き込むことはできるのでしょうか。 できます。 但し、挿入ではなく上書きになってしまいます。 >やはり、文字列を配列に格納し、1回ファイルをクローズして、 >またオープンして追加する?のような処理になるのでしょうか。 そういう方法もありますが、安全性から別のファイルに一度出力した方がいいと思います。 そうすれば、全ての文字列を記憶する必要もなくなります。 1.入出力の両ファイルを開く 2.入力ファイルから、挿入位置まで出力ファイルにコピーする 3.追加する文字を出力ファイルに書き込む 4.入力ファイルの、残りを出力ファイルにコピーする # ここでのコピーは読み込んだデータをそのまま書くことを表しています。 ちなみにfseekではお望みのことは出来ません。 |
No.15555![]() |
Re:ファイルの指定行に文字列を書き出す方法 投稿者---円零(2004/07/15 18:52:06) |
||
>ちなみにfseekではお望みのことは出来ません。 fseekでも行けるみたいです。効率は知りませんが… #include <stdio.h> int main(void){ FILE *fp; int i, ins; unsigned char m = 0, n; char c, filename[256], buf[256]; long getpos, putpos; printf("ファイル名:"); gets(filename); printf("何行目に挿入しますか:"); scanf("%d", &ins); ins--; rewind(stdin); printf("挿入文字列:"); fgets(buf, 256, stdin); n = strlen(buf); if( (fp = fopen(filename, "r+")) == NULL )exit(1); /*** ins行目まで改行を読み飛ばす ***/ for(i = 0; i < ins; i++){ while( (c = fgetc(fp)) != '\n'){ if(c == EOF){ fputc('\n', fp); fseek(fp, 0, SEEK_END); break; } } } /*** 一文字削っては一文字足す ***/ getpos = putpos = ftell(fp); while( buf[m] != EOF ){ fseek(fp, getpos, SEEK_SET); buf[n++] = fgetc(fp); getpos = ftell(fp); fseek(fp, putpos, SEEK_SET); fputc(buf[m++], fp); putpos = ftell(fp); } fclose(fp); return 0; } |
No.15556![]() |
Re:ファイルの指定行に文字列を書き出す方法 投稿者---REE(2004/07/15 19:21:29) |
||
>>ちなみにfseekではお望みのことは出来ません。 > >fseekでも行けるみたいです。効率は知りませんが… なるほど、挿入処理のために使うのですね。 バッファをオーバーフローしないようにリングバッファにして、 1バイト単位ではなく数kbyte単位で行えば、実用レベルの速度にはなりそうですね。 |
No.15572![]() |
ありがとうございました!! 投稿者---ぜろ(2004/07/16 10:41:11) |
||
ZAQさん、NykRさん、REEさん、円零さん、 質問に答えていただいてありがとうございました! 皆さんのアドバイスを参考に解決することが出来ました。 ありがとうございました。 |