- ベストアンサー
ファイル出力について
「test1」というファイルの最後の3行を「test2」というファイルに出力する。 というプラグラムはどのように組み立てればいいのでしょうか? (test1) 1行目の文 2行目の文 3行目の文 4行目の文 5行目の文 6行目の文 ↓ (test2) 4行目の文 5行目の文 6行目の文
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
ファイルの行自身をバッファする方法は、バッファーオーバーフローの危険性があります。 対象がファイルの場合fseek()が可能ですから、改行のあった位置だけを記憶しておき、そこまで戻って最後の3行を出力することができます。 -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- #include <stdlib.h> #include <stdio.h> #include <errno.h> #define LAST 3 char *prog; void usage(void) { fprintf(stderr,"%s fin [fout]\n", prog); exit(1); } int main(int argc, char *argv[]) { FILE *fin, *fout; int c, i; long last[LAST+1]; prog = argv[0]; if (argc < 1) { usage(); } if ((fin = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "Can't open %s\n", argv[1]); perror(prog); exit(errno); } if (argc <= 2) { fout = stdout; } else if ((fout = fopen(argv[2], "w")) == NULL) { fprintf(stderr, "Can't open %s\n", argv[2]); perror(prog); exit(errno); } for (i = 0; i < LAST+1; i++) { last[i] = 0; } while((c = getc(fin)) != EOF) { if (c == '\n') { for (i = 1; i < LAST+1; i++) { last[i-1] = last[i]; } last[LAST] = ftell(fin); } } fseek(fin, last[0], SEEK_SET); while((c = getc(fin)) != EOF) { putc(c, fout); } fclose(fin); fclose(fout); exit(0); }
その他の回答 (4)
- tatsu99
- ベストアンサー率52% (391/751)
1.内部に3行分のバッファを用意します。 2.test1を読み込み、各行をその場合に順番に格納します。(バッファをサイクリックに使用します。) 3.最後まで、読むと、最後の3行分がバッファに残ります。 4.その内容をtest2に出力します。 以下は、そのサンプル。但し、test2ではなく、画面に表示します。 1)入力ファイルは、パラメータで指定。 2)入力ファイルの1行は1023バイト以内 3)入力ファイルは必ず3行以上存在すること という条件付きです。 --------------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> //最後の3行を表示するプログラム int main(int argc, char *argv[]) { FILE *fp; char buff[3][1024]; int ix = 0; int i; memset(buff,0x00,sizeof(buff)); fp = fopen(argv[1],"r"); if (fp == NULL){ printf("ファイルオープンエラー\n"); exit(0); } while(1){ if (fgets(buff[ix],1024-1,fp) == NULL) break; ix++; if (ix >= 3) ix = 0; } fclose(fp); for (i = 0; i < 3; i++){ printf("%s",buff[ix]); ix++; if (ix >= 3) ix = 0; } return(0); }
とりあえず動いたので・・・ #include<stdio.h> int main(void) { FILE *fp1,*fp2; int i; char test[7][256] = {"#include","stdio.h","BLEACH","大迫","園原","長門","Missing"}; char test2[256]; /****************test1.bin作成****************/ if((fp1 = fopen("test1.bin","wb")) == NULL) { printf("test1.binのオープンに失敗\n"); return -1; } for(i = 0;i < 7;i++) { fwrite(test[i],sizeof(test[0]),1,fp1); } fclose(fp1); /**************test1.bin作成終了**************/ if((fp1 = fopen("test1.bin","rb")) == NULL) { printf("test1.binのオープンに失敗\n"); return -1; } if((fp2 = fopen("test2.bin","wb")) == NULL) { printf("test2.binのオープンに失敗\n"); return -1; } fseek(fp1,-3 * sizeof(test[0]),SEEK_END); for(i = 0;i < 3;i++) { fread(test2,sizeof(test2),1,fp1); fwrite(test2,sizeof(test2),1,fp2); } fclose(fp1); fclose(fp2); /****************test2.bin確認****************/ if((fp2 = fopen("test2.bin","rb")) == NULL) { printf("test2.binのオープンに失敗\n"); return -1; } for(i = 0;i < 3;i++) { fread(test2,sizeof(test2),1,fp2); printf("読み込んだ内容は%sです\n",test2); } fclose(fp2); /**************test2.bin確認終了**************/ return 0; } これでどうですか?
すみません。 fseekの書き方間違えました
こういったことはバイナリ形式のデータなら簡単に出来ると思います。 やり方はfseek(ファイルポインタ,一行のデータサイズ,SEEK_END-2)だと思います。 そしたらtest1の読み込み場所が最後から2つ前の行の最初になり、最後の3行が読み込めるようになると思います。 間違っていたらすいません。