• ベストアンサー

どなたか、教えて下さい(C言語)

ソートされた2つのテキストファイルをマージして、ファイルに出力と標準出力を処理したいのですが、どうしたらいいのか分かりません(泣)参考書など見たりもしているのですが・・・。よろしければ、何かアドバイスやソースを教えていただけるとありがたいです。

質問者が選んだベストアンサー

  • ベストアンサー
  • ilice
  • ベストアンサー率50% (3/6)
回答No.3

参考程度にお願いします 出力関数(データ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); } マージしたデータを保持するかしないか&マージしたらマージしたデータを表示するのか教えてほしいです

altair56
質問者

お礼

ilice様、回答して下いまして、ありがとうございます。 質問内容が不十分で申し訳有りませんでした。C言語の勉強は始めたばかりで、参考書を読みながらも、なかなか前に進めない状態が続いていますが、頑張っていきたいと思っています。もう一度トライしてみます。ilice様、ありがとうございました。

altair56
質問者

補足

”マージしたデータを保持するかしないか”については、 マージしたデータを保持したいと考えています。 ”マージしたらマージしたデータを表示するのか”については、 マージしたデータを画面に表示したいと考えています。

その他の回答 (5)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.6

★ソースでの回答です。 >ソースを教えていただけるとありがたいです。  ↑  私のサンプル・ソースと見比べてみて下さい。 ・分かりやすくするために 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; }

altair56
質問者

お礼

お礼が遅くなり申し訳ありません。詳しくサンプルを出して頂けて 感謝しています。何とか問題をクリアできました。ありがとうございました。 

noname#48699
noname#48699
回答No.5

「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)
回答No.4

プログラムを組まなきゃいけないんですか? 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/

noname#39970
noname#39970
回答No.2

原理だけ 1:file1 open (sorted) 2:file2 open (sorted) 3:file3 open (output) 4:file1とfile2を読みfile3とstdoutへ出力(file1とfile2の終端まで) 5:file1~3 close 判らなくなったら手順4を更に判りやすい手順に展開する

altair56
質問者

お礼

情報を下さってありがとうございます。手順4の処理をどうすればいいのか悩んでいるんですが、strcmp()関数を使ったりすればよいのでしょうか?。(><); もう一度チャレンジしてみます。SAYKA様、ありがとうございますね。

回答No.1

質問の内容が明確でないので、以下の点を明らかにしたら 回答がもらえるかもしれません。 ・「ソートされた2つのテキストファイルをマージ」  というのは、単にマージすればよいのか、  それともさらにソートするのか? ・「ファイルに出力と標準出力を処理したい」  というのはどういう意味なのか?(日本語がヘンです)  マージ(あるいはマージしてソートしたもの)を  別のファイルとして出力したいのか、  元のファイルに上書きしたいのか、  それとも画面に出力したいのか?

altair56
質問者

補足

大変失礼しました。 ・「ソートされた2つのテキストファイルをマージ」 とは、”マージしてソートしたい”という意味です。>< ・「ファイルに出力と標準出力を処理したい」 とは、マージしてソートしたものを、”別のファイルとして出力”と ”画面に出力したいと”という意味です。 何か情報を頂けないでしょうか(泣)。

関連するQ&A