• ベストアンサー

標準出力とファイルに効率的に同じ出力をする方法

C&C++でプログラムしています。 (以下は、できれば、Cの範囲内で行いたいと思います。) 結果の出力を画面とファイル両方に出力しています。 printf("A"); ... printf("Z"); fprintf(fp,"A"); ... fprintf(fp,"Z"); ただし、行数が多い場合には、ほとんど同じプログラムがだぶって書いてあり、画面用50行、ファイル出力用50行で、計100行とプログラム行数も長くなってしまいます。 サブルーチン化するなどの方法で、この2つのルーチンを短く記述することは、できないでしょうか? 例えば、 画面に出力する場合には、 fprintf(fp1,"***"); ファイルに出力する場合には、 fprintf(fp2,"***"); として、どちらに出力するかによってファイル指定子を変更できると良いのですが、可能でしょうか? よろしくお願い致します。

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

  • ベストアンサー
noname#48699
noname#48699
回答No.5

No4です。 (全然、「美しくない」=「プログラム的でない」と思いますが・・★ご要望を尊重して・・・、ブツブツ・・) #include <stdio.h> FILE *fgFile; void OrgPrn( char cStr[], int iVal ) {  char cFormat[64];  sprintf( cFormat, "%s%20d\n", cStr, iVal ); // ★出力フォーマットの一元化  fprintf( stdout, cFormat );  fprintf( fgFile, cFormat ); } void main() {  int nline = 1, C = 2, Nelm = 3, Nquad = 4, Ntria = 5, Nbeam = 6, Nbar = 7;  fgFile = fopen( "Test.txt", "w" );  OrgPrn( "Total Number of Line__= ", nline );  OrgPrn( "Total Number of Node__= ", C );  OrgPrn( "Total Number of Element = ", Nelm );  OrgPrn( "Total Number of CQUAD4_= ", Nquad );  OrgPrn( "Total Number of CTRIA_ = ", Ntria );  OrgPrn( "Total Number of CBEAM_ = ", Nbeam );  OrgPrn( "Total Number of CBAR__= ", Nbar );  fclose( fgFile ); } 注:インデントに全角空白を用いています(エディタでタブコードに)。 ☆やっぱ、データとプログラムは別々に・・ぶつぶつ・・(しつこい)。 年寄りの鼻水じゃなかった、年寄りの◇◇水・・・?、残念。

yyamada10
質問者

お礼

お忙しいところご教示ありがとうございました。 おかげさまで、プログラムの行数が半分程度になって、すっきりすることができました。どうもありがとうございました。stdoutについては、他の変数に入れられないので、そのまま使うしかないものと理解しました。 全然、美しくないプログラムとのお叱りを受けており、今後、精進して、改善していきたいと思います。 今後ともよろしくお願い致します。

その他の回答 (4)

noname#48699
noname#48699
回答No.4

★根本的に、《考え方or発想》を変えたら如何でしょう。 質問者様は、50行分のテキストデータを、プログラムソース中にダブルコーテーションで括って入力しようとしています。 まず、このテキストデータのみを、ex)hoge.txt とファイル化すればいいのでは・・・(キーボードから入力する手間は同じ)。 そしてプログラムは、これを読み込んで「画面に出力する」機能にすればよいのでは。 要約すると、質問者様は、 『プログラムで、◆表示しながらファイルを◆作成する』 ですが、私の提案は、 『あらかじめ◆作成したファイルを、プログラムで、読み込み◆表示する』です。 ★この方法で、なさろうとしている事に、不具合がありましたら補足願います。 ・なさろうとしている事を具体的に。 ・不具合を具体的に。 以上、2点補足をお願いします。

yyamada10
質問者

補足

私の説明がうまくできなくて申し訳ありません。 入力ではなくて出力しようと思っています。 下記のような感じで、標準出力とファイルの2カ所に出力したいと思っており、今の状況ですと、ファイルポインタを fp=stdoutとfp=fp2(ファイルポインタ)で変更すれば、短い行数で重複することなく、できるのではないかと思っていますが、いかがでしょうか? fprintf(fp,"Total Number of Line = %20d\n",nline); fprintf(fp,"Total Number of Node = %20d\n",Ngrid); fprintf(fp,"Total Number of Element = %20d\n",Nelm); fprintf(fp,"Total Number of CQUAD4 = %20d\n",Nquad); fprintf(fp,"Total Number of CTRIA = %20d\n",Ntria); fprintf(fp,"Total Number of CBEAM = %20d\n",Nbeam); fprintf(fp,"Total Number of CBAR = %20d\n",Nbar); 以前は、これに、 printf("Total Number of CBAR = %20d\n",Nbar); がずらずら並んで美しくなかったのです。 ご指導よろしくお願い致します。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

> サブルーチン化するなどの方法で、この2つのルーチンを短く記述することは、できないでしょうか? こうでしょうね。 void func(FILE *fp) {  fprintf(fp,"A");  ...  fprintf(fp,"Z"); } int main() {  func(stdout);  func(fp);  return 0; }

yyamada10
質問者

補足

ご連絡が遅くなって大変申し訳ありません。非常に良く分かりました。 早速行おうとしたところ、関数にすると引数で渡す変数の数が多くなるので、サブルーチンでない方が良いかと思いました。 そこで、ご教示頂いた方法を応用して、メインで、ファイルポインタを変更して、forループを2回行う方法が良いかと思いました。 1回目は、FILE* fp=stdoutで、2回目は、fp=fp2(ファイルオープンで開いたもの) ただ、こうしたところ、fp=stdoutの代入がうまく行っていないようで、標準出力に出力されません。fpの代わりにstdoutを使うと問題なく行くのですが、何故でしょうか? よろしくお願いします。

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.2

>サブルーチン化するなどの方法で、 >この2つのルーチンを短く記述することは、できないでしょうか? 途中で送信しました。。。; ちなみにこっちは #include <stdarg.h> void print( FILE* fp, const char* fmt, ... ) { va_list arg; va_start( arg, fmt ); vprintf( fmt, arg ); vfprintf( fp, fmt, arg ); va_end( arg ); } みたいなのとか適当につくってそれを呼び出せば良いかと。

yyamada10
質問者

お礼

ご教示ありがとうございました。 自分が未熟なので、プログラム例を理解するのに時間がかかってしまいました。上記の最初のvprintfの時に、stdoutで標準出力できるようにしてみました。おかげさまで、うまく出力できるようになりました。どうもありがとうございました。

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.1

標準ライブラリ関数のprintfを調べれば判ると思いますが、 printfというのは第1引数に「stdout」を指定されたfprintf関数と等価です。

yyamada10
質問者

お礼

ご連絡遅くなって申し訳ありません。 stdoutで標準出力できるのですね。 どうもありがとうございました。

関連するQ&A

  • 複数列でのファイル出力

    こんばんは。 今プログラムを作っていて行き詰っています。 ある計算をした結果を fprintf(fp,%8.8f,x[0][j]); とすれば1行で出力でき、この計算結果を2行で出力するには fprintf(fp,%8.8f %8.8f,x[0][j],x[1][j]); とすればよいのはわかるのですが、 さらに多くの行(例えば100行で出力したい場合にはどのように指定すればよいのでしょうか? %8.8fを100個書くというやり方ではかなり苦労してしまい、困っています。 よろしくお願いします。

  • C言語のファイル出力について

    C言語のfprintfによるファイル出力について教えてください。 fprintfで、下記の例のように、上書きする行を指定することはできますでしょうか? 出力ファイルは.csv形式で、モードは問いません。 例:既に、sample.csvというファイルがあり、中身が、 0 0 0 1 1 1 2 2 2 とします。プログラムのfprintfで、3 3 3という出力を2行目に上書きし、 0 0 0 3 3 3 2 2 2 と変更する。 もし上記の方法をご存知でしたら、ご教授いただけましたら幸いです。 よろしくお願いいたします。

  • 複数ファイルの出力

    質問があります。1600個のデータを読み込んで(16個ずつの組で100組)、1番目、3番目、5番目、7番目のデータをss[1].txtとして出力し、同様に2番目、4番目、6番目、8番目のデータをsk[1].txt、9番目、11番目、13番目、15番目のデータをks[1].txt、10番目、12番目、14番目、16番目のデータをkk[1].txtとして出力させます。以下、ss[2].txt,sk[2].txt,ks[2].txt,kk[2].txt・・・に関してはそれぞれ直前のファイルに16を足したデータ(例えばss[2].txtなら、17番目、19番目、21番目、23番目のデータを出力)を出力させるというプログラムです。 以下に自分で作ったプログラムを掲載します。 void ecg_rr(fp,data_max) FILE *fp; { int i,j=0; int c=1; char fname[64]; data[0][i]=trend_data[0][i]; for(i,j=0;i<100,j<100;i++,j++) { sprintf(fname,"ss[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][0+j*16]); fprintf(fp,"%8.8f\n",data[0][2+j*16]); fprintf(fp,"%8.8f\n",data[0][4+j*16]); fprintf(fp,"%8.8f\n",data[0][6+j*16]); sprintf(fname,"sk[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][1+j*16]); fprintf(fp,"%8.8f\n",data[0][3+j*16]); fprintf(fp,"%8.8f\n",data[0][5+j*16]); fprintf(fp,"%8.8f\n",data[0][9+j*16]); fclose(fp); /*ks,kkに関しても同様*/ } } これだと100個ずつファイルを出力できるのですが、データが全て0として出力されてしまいます。

  • ファイル入力

    1 20 2 30 3 95 4 52 5 90 3 Maximum  上記の様な入力ファイルinput.datのうち1~5行目のデータを表示するプログラムを作っています。  6行目は空白で、7行目は2列目の中で最大値をとる行の1列目の数値が入っています。  1列目の数値は最後の行を除いて重複することはありません。  入力データの行数はファイルによって最大20行まで変動します。列数は2列で固定です。  以下のプログラムのままでは6行目以降のデータも読み取ってしまい、出力がおかしくなってしまいます。  1~5行目のデータのみ出力するにはどうしたらよいでしょうか。  ご存知の方、お手数ですが教えてください。よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #define row 20 #define col 2 int main(){ int i,j,data[20][2]; FILE *fp; if((fp=fopen("input.dat","r"))==NULL){ fprintf(stderr,"Cannot open file input.dat\n"); exit(1); } for(i=0;i<row;i++){ for(j=0;j<col;j++){ fscanf(fp,"%d",&data[i][j]); printf("%d ",data[i][j]); } printf("\n"); } fclose(fp); return 0; }

  • バイナリファイルをテキストファイルに変換する方法を教えて頂けませんか。

    こんにちは。 バイナリファイルをテキストファイルのように読み込んだり、書き込んだりすることは可能でしょうか。バイナリファイルをテキストファイルとして扱う良い方法があれば是非ご教授頂きたいです。 以下は自分なりに考えたプログラムなのですが、すごく文字化けして出力されてしまいます。どこがいけないんでしょうか。 ####プログラム#### #include<stdio.h> int main(){ FILE *fp,*fp2; char str[1024]; //file.txtはバイナリファイルなのでバイナリモードで開く if((fp = fopen("file.txt","rb")) == NULL){ printf("file.txt:open error"); exit(-1); } //out.txtはテキストファイルとして保存したいのでテキストモードで開く if((fp2 = fopen("out.txt","at")) == NULL){ printf("out.txt:open error"); exit(-1); } //一行ずつバイナリファイルをテキストファイルにして保存 while((fgets(str,1024,fp)) != NULL){ printf("%s\n",str); fprintf(fp2,"%s\n",str); } fclose(fp); fclose(fp2); return 0; } ####ここまで#### 以下が出力されたテキストファイル(out.txt)です。 ^A^Dc ^A^D^L<87> ^Y<98>X^?m?;^D&ordm;?^QI&egrave;&Ccedil; ^A^Dc ^A^D^L<87> ^Y<98>X^?m?;^D&ordm;?^QI0g 酷い文字化けを起こしてしまっています。 解決方法をご存知であれば教えて頂けないでしょうか。どうぞよろしくお願いします。

  • 複数テキストファイルを読み込み、複数テキストファイルの出力

    質問は100個のテキストファイル(それぞれ10個のデータを含む)を読み込み、それぞれのテキストファイルから5個ずつデータを抽出し、200個のテキストファイルとして出力するというプログラムについての質問です。 以下が僕の作ったファイル出力部分のプログラムです。 /************/ void ecg_rr(fp,data_max) FILE *fp; { int b,i=0; int c=1; char fname[64]; data[0][i]=trend_data[0][i]; for(i=0;i<100;i++) sprintf(fname,"ss[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][0]); fprintf(fp,"%8.8f\n",data[0][2]); fprintf(fp,"%8.8f\n",data[0][4]); fprintf(fp,"%8.8f\n",data[0][6]); fclose(fp); sprintf(fname,"sk[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][1]); fprintf(fp,"%8.8f\n",data[0][3]); fprintf(fp,"%8.8f\n",data[0][5]); fprintf(fp,"%8.8f\n",data[0][9]); fclose(fp); } 複数ファイルの読み込み方がわからず、自分のプログラムだと1つのテキストファイルしか読み込めないので、16_4.batを作り、その中身を 16_4 読み込むテキストファイル名1.txt ss[1] 16_4 読み込むテキストファイル名1.txt sk[1] 16_4 読み込むテキストファイル名2.txt ss[2] 16_4 読み込むテキストファイル名2.txt sk[2] ・・・ とやったのですが、うまくいきませんでした。 どうすればよいのでしょうか。

  • 0x00をファイル出力

    #define TEST 0x00 FILE *fp; UCHAR wbuf[1]; wbuf[0] = TEST; if((fp=fopen("test.txt", "w"))==NULL){  printf("open error\n"); } fprintf(fp,"%s",wbuf[0]); fclose(fp); 以上がプログラムでこれを実行するとtest.txtには 文字化けして書き込まれます。 ファイルに0x00と表示させる為にはどうしたらいいですか?

  • ファイルの入力、出力

    #include<stdio.h> int main(){ int a,b; FILE *fp0, *fp1;   fp0 = fopen("test1.dat", "r"); if( fp0 == NULL ){ printf("Cannot open test1.dat"); exit(1); } fp1 = fopen("file.txt", "w"); while((fscanf(fp0, "%d %d", &a,&b)) != EOF){ fprintf(fp1, "%d %d\n", a*a,b*b); } fclose(fp0); fclose(fp1); return(0); } test1.datファイルを読み込んで、変数a,bに値をいれ、 その二乗結果をfile.txtに書き込むプログラムなのですが test1.datファイルに書き込まれてる値をどのようにa,bに代入されているのかわかりません。 例えば test1.datが 1 2 3 4 5 であると、 file.txtには 1 4 9 16 25 16 と書き込まれています。 test1.datが 1 1 2 2 3 3 であると file.txtには 1 1 4 4 9 9 となっています。 どのように、変数に値が入るのでしょうか??

  • 画面のテキストをファイル出力

    画面に表示したテキストをファイルに出力する方法はありませんか。 fprintfを画面出力と同時に実行すればよいのですが、 fprintfをプログラムに追加していくとフローチャートを 書き直さなければならないので何か方法があれば教えてください。 お願いします。 環境 windows XP borland c++ 5.5

  • fgetsでファイルの内容を読み込む

    キーボードから読みたいファイル名を入力し 指定した行数だけファイルの内容を出力する プログラムを作りました。 ちゃんと動作するソースは作れたのですが、 へんなところ(無駄な文など)がないか どなたか見て頂けないでしょうか。 ソースが長くて申し訳ありません。 課題で、答えはあるのですが、ソースを チェックしてもらえる人が回りに いない状況です。 どうぞ宜しくお願いします。 printf("出力するファイル名を入力してください-->"); gets(s); while((fp = fopen(s, "r")) == NULL) { printf("指定されたファイルがありません\n"); printf("再度入力して下さい-->"); fflush(stdin); gets(s); } printf("出力する行数を入力して下さい-->"); fflush(stdin); scanf("%d",&l); while(fgets(s, 256, fp)!=NULL){ printf("%s", s); l--; if(l==0){ fclose(fp); return 0; } } fclose(fp);

専門家に質問してみよう