- ベストアンサー
標準出力とファイルに効率的に同じ出力をする方法
C&C++でプログラムしています。 (以下は、できれば、Cの範囲内で行いたいと思います。) 結果の出力を画面とファイル両方に出力しています。 printf("A"); ... printf("Z"); fprintf(fp,"A"); ... fprintf(fp,"Z"); ただし、行数が多い場合には、ほとんど同じプログラムがだぶって書いてあり、画面用50行、ファイル出力用50行で、計100行とプログラム行数も長くなってしまいます。 サブルーチン化するなどの方法で、この2つのルーチンを短く記述することは、できないでしょうか? 例えば、 画面に出力する場合には、 fprintf(fp1,"***"); ファイルに出力する場合には、 fprintf(fp2,"***"); として、どちらに出力するかによってファイル指定子を変更できると良いのですが、可能でしょうか? よろしくお願い致します。
- みんなの回答 (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 ); } 注:インデントに全角空白を用いています(エディタでタブコードに)。 ☆やっぱ、データとプログラムは別々に・・ぶつぶつ・・(しつこい)。 年寄りの鼻水じゃなかった、年寄りの◇◇水・・・?、残念。
その他の回答 (4)
★根本的に、《考え方or発想》を変えたら如何でしょう。 質問者様は、50行分のテキストデータを、プログラムソース中にダブルコーテーションで括って入力しようとしています。 まず、このテキストデータのみを、ex)hoge.txt とファイル化すればいいのでは・・・(キーボードから入力する手間は同じ)。 そしてプログラムは、これを読み込んで「画面に出力する」機能にすればよいのでは。 要約すると、質問者様は、 『プログラムで、◆表示しながらファイルを◆作成する』 ですが、私の提案は、 『あらかじめ◆作成したファイルを、プログラムで、読み込み◆表示する』です。 ★この方法で、なさろうとしている事に、不具合がありましたら補足願います。 ・なさろうとしている事を具体的に。 ・不具合を具体的に。 以上、2点補足をお願いします。
補足
私の説明がうまくできなくて申し訳ありません。 入力ではなくて出力しようと思っています。 下記のような感じで、標準出力とファイルの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)
> サブルーチン化するなどの方法で、この2つのルーチンを短く記述することは、できないでしょうか? こうでしょうね。 void func(FILE *fp) { fprintf(fp,"A"); ... fprintf(fp,"Z"); } int main() { func(stdout); func(fp); return 0; }
補足
ご連絡が遅くなって大変申し訳ありません。非常に良く分かりました。 早速行おうとしたところ、関数にすると引数で渡す変数の数が多くなるので、サブルーチンでない方が良いかと思いました。 そこで、ご教示頂いた方法を応用して、メインで、ファイルポインタを変更して、forループを2回行う方法が良いかと思いました。 1回目は、FILE* fp=stdoutで、2回目は、fp=fp2(ファイルオープンで開いたもの) ただ、こうしたところ、fp=stdoutの代入がうまく行っていないようで、標準出力に出力されません。fpの代わりにstdoutを使うと問題なく行くのですが、何故でしょうか? よろしくお願いします。
- aris-wiz
- ベストアンサー率38% (96/252)
>サブルーチン化するなどの方法で、 >この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 ); } みたいなのとか適当につくってそれを呼び出せば良いかと。
お礼
ご教示ありがとうございました。 自分が未熟なので、プログラム例を理解するのに時間がかかってしまいました。上記の最初のvprintfの時に、stdoutで標準出力できるようにしてみました。おかげさまで、うまく出力できるようになりました。どうもありがとうございました。
- aris-wiz
- ベストアンサー率38% (96/252)
標準ライブラリ関数のprintfを調べれば判ると思いますが、 printfというのは第1引数に「stdout」を指定されたfprintf関数と等価です。
お礼
ご連絡遅くなって申し訳ありません。 stdoutで標準出力できるのですね。 どうもありがとうございました。
お礼
お忙しいところご教示ありがとうございました。 おかげさまで、プログラムの行数が半分程度になって、すっきりすることができました。どうもありがとうございました。stdoutについては、他の変数に入れられないので、そのまま使うしかないものと理解しました。 全然、美しくないプログラムとのお叱りを受けており、今後、精進して、改善していきたいと思います。 今後ともよろしくお願い致します。