- ベストアンサー
どなたか、教えて下さい(C言語)
ソートされた2つのテキストファイルをマージして、ファイルに出力と標準出力を処理したいのですが、どうしたらいいのか分かりません(泣)参考書など見たりもしているのですが・・・。よろしければ、何かアドバイスやソースを教えていただけるとありがたいです。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
参考程度にお願いします 出力関数(データ1[][],データ2[][]){ FILE *fo; int i,j; fo=fopen(出力ファイルのパス,"w"); i=j=0 while(1){ if(i<データ1の読み込み数&&j<データ2の読み込み数){ if(データ1[i]>=データ2[j]){ fprintf(fo,"%s\n",データ1[i]); printf("%s\n",データ1[i++]); }else{ fprintf(fo,"%s\n",データ2[j]); printf("%s",データ2[j++]); } }else if(i==データ読み込み数||j==データ読み込み数){ if(i==データ1読み込み数){ fprintf(fo,"%s\n",データ2[j]); printf("%s",データ2[j++]); }else if(j==データ読み込み数){ fprintf(fo,"%s\n",データ1[i]); printf("%s\n",データ1[i++]); } }else if(i==データ読み込み数&&j==データ読み込み数) break; } fclose(fo); } マージしたデータを保持するかしないか&マージしたらマージしたデータを表示するのか教えてほしいです
その他の回答 (5)
- Oh-Orange
- ベストアンサー率63% (854/1345)
★ソースでの回答です。 >ソースを教えていただけるとありがたいです。 ↑ 私のサンプル・ソースと見比べてみて下さい。 ・分かりやすくするために main()、merge_sort()、merge_fputs() の3つの関数に 処理を分けました。マージ処理は merge_sort() 関数です。昇順、降順対応。 (解説はしませんので解読してね!) #include <stdio.h> #include <string.h> /* このファイルで使用する定数 */ #define FILE_1 "file1.txt" #define FILE_2 "file2.txt" #define FILE_OUT "merge.txt" // ファイル出力と標準出力(マクロ関数にしても良い) void merge_fputs( FILE *fo, const char string[] ) { fputs( string, fo ); // ファイル出力 fputs( string, stdout ); // 標準出力 } // 2つのファイルをマージする関数(本題) void merge_sort( FILE *fo, FILE *fp1, FILE *fp2 ) { char buff1[ 1024 ]; char buff2[ 1024 ]; int sw, cmp; // 最初の読み込み位置へジャンプ goto start; for ( ; ; ){ cmp = +strcmp( buff1, buff2 ); // 昇順(小さい順にマージ出力) // cmp = -strcmp( buff1, buff2 ); // 降順(大きい順にマージ出力) if ( cmp < 0 ){ // file1<file2…file1を出力(昇順時) merge_fputs( fo, buff1 ); if ( fgets(buff1,sizeof(buff1),fp1) != NULL ) continue; sw = 2; } else if ( cmp > 0 ){ // file1>file2…file2を出力(昇順時) merge_fputs( fo, buff2 ); if ( fgets(buff2,sizeof(buff2),fp2) != NULL ) continue; sw = 1; } else{ // file1=file2…両方を出力(昇順時) merge_fputs( fo, buff1 ); merge_fputs( fo, buff2 ); start:sw = 0; if ( fgets(buff1,sizeof(buff1),fp1) != NULL ) sw |= 1; if ( fgets(buff2,sizeof(buff2),fp2) != NULL ) sw |= 2; } switch ( sw ){ // 読み込めなかった場合の処理(終了) case 0: return; case 1: merge_fputs( fo, buff1 ); return; case 2: merge_fputs( fo, buff2 ); return; } } } // メイン関数(ファイルのオープン/クローズの処理) int main( void ) { FILE *fp1 = NULL; // ソートされたファイル1 FILE *fp2 = NULL; // ソートされたファイル2 FILE *fo = NULL; // マージ出力のファイル int merge = 0; // マージ実行のフラグ if ( (fp1 = fopen(FILE_1,"r")) != NULL ){ if ( (fp2 = fopen(FILE_2,"r")) != NULL ){ if ( (fo = fopen(FILE_OUT,"w")) != NULL ){ merge_sort( fo, fp1, fp2 ); merge = 1; fclose( fo ); } fclose( fp2 ); } fclose( fp1 ); } if ( merge ){ printf( "2つのファイルをマージしました。\n" ); } else{ if ( fp1 == NULL ) printf( "%s ファイルが見つかりません。\n", FILE_1 ); if ( fp2 == NULL ) printf( "%s ファイルが見つかりません。\n", FILE_2 ); if ( fo == NULL ) printf( "%s ファイルに書き込めません。\n", FILE_OUT ); } return 0; }
お礼
お礼が遅くなり申し訳ありません。詳しくサンプルを出して頂けて 感謝しています。何とか問題をクリアできました。ありがとうございました。
「C言語の勉強は始めたばかりで」とのことで・・参考になれば。 インデント、タブが消えてしまって見づらくて申し訳ない・・・(私なりのこだわりがあるのですが、残念) (なお、DOS窓では2コマンド(COPY,SORT)でできちゃう・・・) (それをいっちぁお終いかな・・なにかと楽したい中高年) ・要は、ブァッファに読み込んだものが、どんな条件でも出力前に上書き読み込みされないように・・ということかな。 ・アルゴリズムは趣味の世界ともいえる。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define A_END 0x01 #define B_END 0x10 #define ALL_END 0x11 void main() { int iHappyEnd = 0x00, iWork, iSw; char cBufA[1024], cBufB[1024]; FILE *fpA, *fp2, *fpB; fpA = fopen( "nyuryokuA.txt", "r" ); fp2 = fopen( "NewData.txt", "w" ); fpB = fopen( "nyuryokuB.txt", "r" ); if( fpA == NULL ){ fprintf( stderr, "nyuryokuA.txt が有りません" ); exit( 0 ); } if( fpB == NULL ){ fprintf( stderr, "nyuryokuB.txt が有りません" ); exit( 0 ); } fgets( cBufA, 1023, fpA ); // 先行読み込み fgets( cBufB, 1023, fpB ); while( ALL_END != iHappyEnd ){ // 2ファイル共に終了まで if( A_END == iHappyEnd ){ // Aファイルデータ無し fprintf( fp2, "%s", cBufB ); // ファイルに出力 fprintf( stderr, "%s", cBufB ); // 標準出力 if( NULL == fgets( cBufB, 1023, fpB ) ) iHappyEnd |= B_END; continue; } if( B_END == iHappyEnd ){ // Bファイルデータ無し fprintf( fp2, "%s", cBufA ); // ファイルに出力 fprintf( stderr, "%s", cBufA ); // 標準出力 if( NULL == fgets( cBufA, 1023, fpA ) ) iHappyEnd |= A_END; continue; } iSw = strcmp( cBufA, cBufB ); // マージ作業 if( iSw < 0 ){ // A < B fprintf( fp2, "%s", cBufA ); // ファイルに出力 fprintf( stderr, "%s", cBufA ); // 標準出力 if( NULL == fgets( cBufA, 1023, fpA ) ) iHappyEnd |= A_END; continue; } if( iSw > 0 ){ // A > B fprintf( fp2, "%s", cBufB ); // ファイルに出力 fprintf( stderr, "%s", cBufB ); // 標準出力 if( NULL == fgets( cBufB, 1023, fpB ) ) iHappyEnd |= B_END; continue; } fprintf( fp2, "%s", cBufA ); // ファイルに出力 fprintf( stderr, "%s", cBufA ); // 標準出力 fprintf( fp2, "%s", cBufB ); // ファイルに出力 fprintf( stderr, "%s", cBufB ); // 標準出力 if( NULL == fgets( cBufA, 1023, fpA ) ) iHappyEnd |= A_END; // 先行読み込み if( NULL == fgets( cBufB, 1023, fpB ) ) iHappyEnd |= B_END; } fcloseall(); }
- sakusaker7
- ベストアンサー率62% (800/1280)
プログラムを組まなきゃいけないんですか? cat file1 file2 | sort | uniq | tee outfile でできると思いますが。 http://www.jp.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/sort/Attic/ http://www.jp.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/uniq/ http://www.jp.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/tee/
原理だけ 1:file1 open (sorted) 2:file2 open (sorted) 3:file3 open (output) 4:file1とfile2を読みfile3とstdoutへ出力(file1とfile2の終端まで) 5:file1~3 close 判らなくなったら手順4を更に判りやすい手順に展開する
お礼
情報を下さってありがとうございます。手順4の処理をどうすればいいのか悩んでいるんですが、strcmp()関数を使ったりすればよいのでしょうか?。(><); もう一度チャレンジしてみます。SAYKA様、ありがとうございますね。
- motochan7185
- ベストアンサー率18% (6/32)
質問の内容が明確でないので、以下の点を明らかにしたら 回答がもらえるかもしれません。 ・「ソートされた2つのテキストファイルをマージ」 というのは、単にマージすればよいのか、 それともさらにソートするのか? ・「ファイルに出力と標準出力を処理したい」 というのはどういう意味なのか?(日本語がヘンです) マージ(あるいはマージしてソートしたもの)を 別のファイルとして出力したいのか、 元のファイルに上書きしたいのか、 それとも画面に出力したいのか?
補足
大変失礼しました。 ・「ソートされた2つのテキストファイルをマージ」 とは、”マージしてソートしたい”という意味です。>< ・「ファイルに出力と標準出力を処理したい」 とは、マージしてソートしたものを、”別のファイルとして出力”と ”画面に出力したいと”という意味です。 何か情報を頂けないでしょうか(泣)。
お礼
ilice様、回答して下いまして、ありがとうございます。 質問内容が不十分で申し訳有りませんでした。C言語の勉強は始めたばかりで、参考書を読みながらも、なかなか前に進めない状態が続いていますが、頑張っていきたいと思っています。もう一度トライしてみます。ilice様、ありがとうございました。
補足
”マージしたデータを保持するかしないか”については、 マージしたデータを保持したいと考えています。 ”マージしたらマージしたデータを表示するのか”については、 マージしたデータを画面に表示したいと考えています。