• 締切済み

ファイルポインタを使って計算結果をテキストファイルに出力したいのですが…

c++初心者です。電気回路のRLC直列回路の周波数を変え、インピーダンスの実数部、虚数部、絶対値、位相の計算をするプログラムを組んでその結果をファイルポインタを使ってテキストファイルに出力したいのですが、ファイルポインタについていまいち理解できていないため、上手くできません。一応、下のプログラムで計算はできるのですが、テキストファイルに出力する段階でエラーのようなものが表示され、止まってしまいます。プログラムの問題点やファイルポインタについて、どなたか分かりやすく教えて頂けないでしょうか。 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <iostream.h> #include <complex.h> #define Complex complex <double> #define PI 3.141592653 using namespace std; Complex mul(double f); int main() { FILE *fa; double f,a,g,fd,w; double E=10.0; /* 起電力10V */ double R=5.0, L=5.0e-3 ,C=0.50e-3; /* 抵抗5Ω コイル5mH  コンデンサ0.5mF */ Complex z,s,u; fa=fopen("out.txt", "w"); if(fa=NULL){ printf("***error***\n"); exit(1); } printf(" 周波数 実部 虚部 絶対値 位相角\n"); fd=sqrt(1.01); for(f=1.0; f<=1.0e5; f*=fd) { z=mul(f); u=E/z; a=abs(u); g=atan2(imag(u), real(u)); printf("%10.4f %8.4f %8.4f %8.4f %8.4f\n",f,real(u),imag(u),a,g); } fprintf("%10.4f %8.4f %8.4f %8.4f %8.4f\n",f,real(u),imag(u),a,g); fclose(fa); } Complex mul(double f) { double w; double R=5.0,L=5.0e-3,C=0.50e-3; Complex z,s; w=2*PI*f; s=Complex(0.0,1.0)*w; z=R+s*L+1.0/(s*C); return z; }

みんなの回答

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

★jactaへ ・ご指摘有り難うございます。  逆でしたね。→scanf() 系で %lf が double 型なので printf() 系も %lf というのが  間違いでしたね。すっかり思い違いをしていました。  有り難うございました。 ★質問者さんへ ・回答 No.4 の一部に間違いがありました。  回答者 No.5 さんのアドバイスが正しいです。  私の思い違いでした。 ・申し訳ありませんでした。

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

反則御免で指摘します。 #4の回答にある > それと double 型の fprintf() 指定は『%f』ではなく『%lf』になります。注意! > 今は『%f』でも『%lf』と同様な表示を出力できるみたいですね。→C99 規格の話 fprintfの書式指定は、実引数がdouble型の場合でも%fです。なぜなら、可変個引数にfloat型の値を渡しても、既定の実引数拡張によって暗黙的にdouble型に変換されるからです。 C99では%lfも使えるようになりましたが、それはあまりにも間違える人が多いので、やむなく許容する仕様になっただけです。

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

★C++ ではなく C 言語でいきます。 ・ファイルのオープン、読み書き、クローズについて説明します。  下のサンプルをどうぞ。 サンプル: FILE *fp; if ( (fp = fopen("ファイル名","w")) == NULL ){  printf( "ファイルがオープンできません。\n" );  exit( 1 ); } fputc( 'A', fp ); ←1文字を出力 fputs( "あいうえお", fp ); ←文字列を出力 fprintf( fp, "%10.4lf\n", a ); ←書式制御付きの文字列を出力 fclose( fp ); その他: ・printf( "文字列" )  fprintf( fp, "文字列" )  となります。  fprintf() には fp を最初の引数に指定します。その後の引数は printf 関数と同じです。 ・よって、ファイルには  fprintf( fp, " 周波数 実部 虚部 絶対値 位相角\n" );  fprintf( fp, "%10.4lf %8.4lf %8.4lf %8.4lf %8.4lf\n", f, real(u), imag(u), a, g );  となります。 ・あとファイルポインタは習慣的に fp という名前を私は良く使います。→もちろん自由な名前で構わないが…。  それと double 型の fprintf() 指定は『%f』ではなく『%lf』になります。注意!  今は『%f』でも『%lf』と同様な表示を出力できるみたいですね。→C99 規格の話 最後に: ・無理に C++ で記述しないで最初は C 言語で記述してみたらどうでしょうか。  C++ でも C 関数は利用できるようですが、標準入出力は cin、cout、cerr などを C++ では使います。  混同しているのでどちらかに統一しましょう。→最初は C 言語かな。 ・以上。おわり。

  • Werner
  • ベストアンサー率53% (395/735)
回答No.3

> エラーのようなものが表示され、止まってしまいます。 エラーのようなものが表示されたなら、ちゃんと書いてください。 とりあえず、明らかにおかしい点は > if(fa=NULL){ faにNULLを代入してしまっている。 > fprintf("%10.4f %8.4f %8.4f %8.4f %8.4f\n",f,real(u),imag(u),a,g); fprintfの第1引数がファイルポインタになっていない。 # C++なら.hなしのcmathやiostreamをincludeしたほうがらしくないか。

noname#50176
noname#50176
回答No.2

printf(" 周波数 実部 虚部 絶対値 位相角\n"); fd=sqrt(1.01); for(f=1.0; f<=1.0e5; f*=fd) { z=mul(f); u=E/z; a=abs(u); g=atan2(imag(u), real(u)); printf("%10.4f %8.4f %8.4f %8.4f %8.4f\n",f,real(u),imag(u),a,g); fprintf("%10.4f %8.4f %8.4f %8.4f %8.4f\n",f,real(u),imag(u),a,g); }・・・※移動した点 fclose(fa); } くくりの位置がずれていたのでは・・・? 元のですとループからぬけた時にカウンタfが1カウンタ超過する ので最大値越えの配列インデックスを参照しエラーと なるんじゃないでしょうか?

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

C++ なら素直に ofstream を使えばいいような気もしますが、 >fprintf("%10.4f %8.4f %8.4f %8.4f %8.4f\n",f,real(u),imag(u),a,g); 第一引数にファイルポインタが指定できていないだけでは? fprintf(fa, "%10.4f %8.4f %8.4f %8.4f %8.4f\n",f,real(u),imag(u),a,g); に修正するとどう?

関連するQ&A

  • 出力内容を新しいテキストファイルで保存するには?

    プログラム #include <stdio.h> #include <string.h> main() { char text[100]; char a[20], b[20], c[20], d[20], e[20], f[20]; char fname[20]; int i = 1; FILE *fp; printf("■ファイル名>>"); scanf("%s",fname); fp=fopen(fname,"r"); if((fp = fopen(fname,"r")) == NULL){ printf("ファイルをオープンできませんでした。\n"); return 1; } else{ printf("ファイルをオープンしました。\n"); } while( fscanf(fp, "%s", text) != EOF){ sscanf(text, "%[^,], %[^,], %[^,], %[^,], %[^,], %[^\0]", a, b, c ,d, e, f); printf("%d回目\n",i++); printf("全文:%s\n",text); printf("1つ目:%s\n",a); printf("2つ目:%s\n",b); printf("3つ目:%s\n",c); printf("4つ目:%s\n",d); printf("5つ目:%s\n",e); printf("6つ目:%s\n\n",f); } } テキストファイル ABCD,EFGH,IJKL,MNOP,QRST,UVWXWZ abcd,efgh,ijkl,mnop,qrst,uvwxyz あいうえお,かきくけこ,さしすせそ,たちつてと,なにぬねの,はひふへほ テキストファイルから文字列を読み込み、変換させて出力させた内容を他のテキストファイルに保存するにはどのようにしたらいいのでしょうか?

  • 0と1のファイルへの書き込み、出力

    c言語で0と1の乱数を生成し、ファイルに出力したいのですが、出力がおかしくなってしまいます。 正しく0と1をファイルに書き込み、出力するにはどうしたらいいでしょうか。 わかる方いらっしゃいましたら教えてください。 お願い致します。 #include<stdio.h> #include <stdlib.h> #include <time.h> #define max 3000000 #define nrand(n) (int)((double)n*rand()/RAND_MAX) /* 0以上n未満の整数を返す */ int main() {   FILE *Wf;   char W_filename[20];   int *W=(int *)malloc(sizeof(int) * max);   printf("入力ファイル名 : "); scanf("%s",W_filename);   if( ( Wf=fopen(W_filename,"w") ) == NULL ) printf("ファイルを開けません\n");   else   {     for(i=0;i<max;i++)     {     W[i]=nrand(2);     fprintf(Wf,"%d ",W[i]);    }   }   fclose(Wf);   free(W); } 出力が ‰‱‱‰‱‱‰‱‱‰‰‰‰‱‰‱‰‱‰‰ のようになってしまいます。 Wにはちゃんと0か1が入っているみたいなのですが・・・

  • C言語 構造体 2

    三つの構造体α、β、γの実数部、虚数部の値(実数)をそれぞれ入力し、 (α+γ)(γ+β)を求めて表示せよ。 ただし、複素数を、実数部と虚数部に対応するメンバで構成される構造体として表し、複素数の加算用関数c_add()と乗算用関数c_mul()を作成して、これを利用すること。 これらの関数は、sとtを複素数を表す構造体としたとき、c_add(s,t)、c_mul(s,t)と呼び出すと、それぞれ戻り値として、sとtを加算、または乗算した結果である複素数の構造体を返すものとする。 という問題なのですが。。。。 #include<stdio.h> int main(void){ struct complex{ double real; double imaginary; }; struct complex[3]; double real; double imag; printf("α= "); scanf("%d,&real); scanf(%d,&imag); printf("β= "); scanf("%d,&real); scanf(%d,&imag); printf("γ="); scanf("%d,&real); scanf(%d,&imag); (α+γ)=c_add(α,γ); (β+γ)=c_add(β,γ); (α+γ)(β+γ)=c_mul(α+γ,β+γ) result=(α+γ)(β+γ) printf("result= "); まで友達と考えてみたのですが、このあとどうしたらいいのかわかりません>< どなたかお教えください。。お願いします。。。

  • テキストファイルに出力した結果の加算

     キーボードから'a'を入力した時点で'1'をテキストに書き込み、何も入力しない時は'0'を書き込むプログラムを作りました。  このプログラムを改良して、実行するたびに前のテキストの内容に実行結果を足していくようなプログラムを作りたいのですがどのように改良していけばよいでしょうか?  例えば、1回目に入力した時点と2回目に入力した時点がかぶっていたらテキストファイルにはその時点の数値が'2'となるようにしていきたいのです。  プログラムは以下です。 ------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <cxcore.h> #include <highgui.h> #include "cv.h" #include "image.h" #include "avi_w.h" //IplImage IplImage* src; IplImage* gray; IplImage* file; int main(void) { char wname[] = "input"; CvCapture* capture; IplImage *frame=NULL; char* captureWindow = "Capture"; int key; int count; int score[10000][1]; int i; int j=1; int k=0; char filename[256]; FILE *fp,*fq; time_t timer; struct tm *date; char str[1000]; //AVIファイルの読み込み・出力 capture = cvCaptureFromFile("video.avi"); cvNamedWindow(wname,1); frame = cvQueryFrame(capture); //キャプチャサイズを知るために画像取得 //変数群の定義 CvVideoWriter* VideoWriter = NULL; char* file = "movie.avi"; // 出力ファイル名 double fps = 30.0; // ビデオのフレームレート //ビデオファイル書き込みの設定 VideoWriter = cvCreateVideoWriter(file,-1,fps,cvSize(frame->width,frame->height),1); //画像表示ウィンドウの出現位置指定 cvMoveWindow(wname, 300, 300); //ファイルオープン fp = fopen("frame.txt","w"); fprintf(fp,"フレーム\n"); for(count=1;;count++){ frame = cvQueryFrame(capture); cvShowImage(wname,frame); key = cvWaitKey(30); if(frame == NULL) break; /*キー入力*/ else if(key == 'q') break; else if(key == 'a'){ //ビデオファイル書き込み cvWriteFrame(VideoWriter,frame); key = cvWaitKey(1); printf("aが%dフレーム目で入力されました\n",count); /*現在時間の取得*/ timer = time(NULL);/* 経過時間を取得 */ date = localtime(&timer);/* 経過時間を時間を表す構造体 date に変換 */ strftime(str, 255, "%Y, %B, %d, %A %p%I:%M:%S", date); printf("%s\n\n", str); //テキストファイルに出力 fprintf(fp,"[%03d] ",count); fprintf(fp," 1\n"); } else{ fprintf(fp,"[%03d] ",count); fprintf(fp," 0\n"); } } cvReleaseVideoWriter(&VideoWriter); cvReleaseCapture( &capture ); cvDestroyAllWindows(); fclose(fp); return 0; } ----------------------------------------------

  • C言語:2つの複素数(分数)の四則演算

    下記のプログラムを組んでみて、発展として分数の形で複素数の四則演算のプログラムを作りたいのですが、どうにもややこしく、困っています。 よろしければ御指導よろしくお願いします。 /* 複素数を表す構造体 2つの複素数の四則演算 */ #include <stdio.h> #include <stdlib.h> typedef struct { double real; /* 実数部分 */ double imag; /* 虚数部分 */ }COMPLEX; /* 二つの複素数の和を返す */ COMPLEX comp_add(COMPLEX x, COMPLEX y) { COMPLEX tmp; tmp.real = x.real + y.real; /* 実数部分の和 */ tmp.imag = x.imag + y.imag; /* 虚数部分の和 */ return (tmp); } /* 二つの複素数の差を返す */ COMPLEX comp_sub(COMPLEX x, COMPLEX y) { COMPLEX tmp; tmp.real = x.real - y.real; /* 実数部分の差 */ tmp.imag = x.imag - y.imag; /* 虚数部分の差 */ return (tmp); } /* 二つの複素数の積を返す */ COMPLEX comp_mul(COMPLEX x, COMPLEX y) { COMPLEX tmp; tmp.real = (x.real * y.real) - (x.imag * y.imag); tmp.imag = (x.real * y.imag) + (y.real * x.imag); return (tmp); } /* 二つの複素数の商を返す */ COMPLEX comp_div(COMPLEX x, COMPLEX y) { COMPLEX tmp; tmp.real =(x.real*y.real+x.imag*y.imag)/(y.real*y.real+y.imag*y.imag); tmp.imag = (x.imag*y.real-x.real*y.imag)/(y.real*y.real+y.imag*y.imag); return (tmp); } int main( int argc, char **argv ) { COMPLEX a, b, c; a.real = strtod( argv[1], NULL ); a.imag = strtod( argv[2], NULL ); b.real = strtod( argv[3], NULL ); b.imag = strtod( argv[4], NULL ); c = comp_add(a, b); /* 複素数の和を c に代入 */ printf( "(%f+j%f)*(%f+j%f)=(%3.1lf+j%3.1lf)\n", a.real,a.imag,b.real,b.imag,c.real,c.imag ); c = comp_sub(a, b); /* 複素数の差を c に代入 */ printf( "(%f+j%f)*(%f+j%f)=(%3.1lf+j%3.1lf)\n", a.real,a.imag,b.real,b.imag,c.real,c.imag ); c = comp_mul(a, b); /* 複素数の積を c に代入 */ printf( "(%f+j%f)+(%f+j%f)=(%3.1lf+j%3.1lf)\n", a.real,a.imag,b.real,b.imag,c.real,c.imag ); c = comp_div(a, b); /* 複素数の商を c に代入 */ printf( "(%f+j%f)+(%f+j%f)=(%3.1lf+j%3.1lf)\n", a.real,a.imag,b.real,b.imag,c.real,c.imag ); return( 0 ); }

  • シンプソン法の出力結果について

    シンプソン法の区間分割数nを10~100まで10ずつ増やして計算値と計算誤差を求めるプログラムを書きに作成したのですが、出力結果に-7.341865999405491E-5などとあります。この「E-数字」とはJavaではどういうこと示しているのですか? また、計算誤差の求め方は下記のプログラムでいいのですか? public class Simpson { static double f(double x) { // ここに任意の被積分関数を記述 double y = Math.exp(- x * x / 2) / Math.sqrt(2.0 * Math.PI); return y; } public static void main(String[] args) { double a = - 1.0, b = 1.0; // 積分範囲 int n = 100; // 区間分割数 for(n=10; n <=100; n+=10){ double h = (b - a) / (double)n; // 分割幅 double s, s1 = 0.0, s2 = 0.0; for (int i = 1; i <= n / 2; i++) { s1 += f(a + (2 * i - 1) * h); } for (int i = 1; i <= n / 2 - 1; i++) { s2 += f(a + 2 * i * h); } s = h / 3.0 * (f(a) + 4.0 * s1 + 2.0 * s2 + f(b)); double suti = (s-0.68269)/0.68269*100;  //計算誤差=(計算値ー真値)/真                                         値×100 System.out.println("区間分割数 =" + n); System.out.println("シンプソン法による計算値 =" + s); System.out.println("シンプソン法による計算誤差 ="+suti+"\n"); } } }

  • ファイルの入出力を行って文字を変換する

    入力するファイルにa~zを記入しておき、 出力するファイルにaなら1、bなら2、zなら26に変換させたいのですがどうしたらよいでしょうか? #include <stdio.h> #include <string.h> #define DELIMITER "/ ," /* 区切り文字 */ int main(void) { FILE *fin,*fout; int count=0; int i; char s[256], s2[256]; char alpha[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; int kazu[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26}; char *taken; char *strch[50]; if( (fin=fopen("file1.txt","r"))==NULL) { printf("入力ファイルがオープンできません\n"); exit(EXIT_FAILURE); } if( (fout=fopen("file2.txt","w"))==NULL) { printf("出力ファイルがオープンできません\n"); exit(EXIT_FAILURE); } while(fgets(s,256,fin)!=NULL) { while (token != NULL) { strch[count]=token; token = strtok(NULL, DELIMITER); count++; } memset(s2, NULL, sizeof(s2)); fprintf(fout,"%d\n",s2); } fclose(fin); fclose(fout); return 0; }

  • JavaScriptの配列について

    var old_array = Array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '<', '#', '/', '>', '%', '.', '*', '0', '!', '?', ':', '=', '|'); var new_array = Array('b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '<', '#', '/', '>', '%', '.', '*', '0', '!', '?', ':', '=', '|'); のような配列があり、 abcと入力するとbcd DEFと入力するとEFG 012と入力すると!23 というようなものを作りたいのですがどうすればいいでしょうか。

  • 浮動小数点数が表示されないんです…。。。

    研究でC言語を使わないといけないんですが、簡単な小数点の表示すらうまくできないんです。誰か助けてください。プログラムの内容はinput.gridというファイルから各変数の値をfscanf関数で読み込み、画面に表示するというごく単純なものでコンパイル、リンクはうまくいくのですが、実行のときにfloating point not loadedと画面に表示され途中で処理が終わってしまいます。同じような経験されたかたいらっしゃいますか?なんとかならないでしょうか??下にプログラムと入力データを記述しておきます。 ・プログラム #include<stdio.h> #include<stdlib.h> main() { int *type; int *t; int *n; double *x; double *y; double *z; double *u; double *v; double *w; double *p; double *rho; FILE *fp_grid,*fp_press ; /*ファイルポインター*/ if((fp_grid=fopen("input.grid","r"))==0){ printf("file not open \n"); exit(1);} if((fp_press=fopen("input.press","w"))==0){ printf("file not open \n"); exit(1);} fscanf(fp_grid,"%d",&t); fscanf(fp_grid,"%d",&n); fscanf(fp_grid,"%f %f %f %f %f %f %f %f",&type,&x,&y,&z,&u,&v,&w,&p,&rho); printf("check\nt=%d,n=%d\n",t,n); printf("%d %f %f %f %f %f %f %f %f",type,x,y,z,u,v,w,p,rho); fclose(fp_grid); return; } 入力データinput.grid 0 21170 0 0.700000 -0.100000 -0.070000 0.000000 0.000000 -0.019927 0.000000 1000.000000

  • ポインタ、関数、アドレス・・・

    はじめまして。 今微分方程式を解かせるプログラムを作る上で、関数に配列を渡したいと考えています。(多変数微分方程式なので) そのため、ポインタを学び、何となくそれについて分かってきたつもりなんですが、いざ試しのプログラムで、コンピュータがちゃんと値を返してくれるかを試しているのですが、どーもうまく値を返してくれません。。。 下に僕が作ったプログラムを載せますので、問題点を指摘してもらえたらうれしいです。 このプログラムで、僕として返してもらいたい値は1.1111です。 よろしくお願いします /******ソースプログラム******/ #include<stdio.h> #include<math.h> double f(int *x); void main() { double x[5]; x[0] = 0.0; x[1] = 1.0; x[2] = 2.0; x[3] = 3.0; x[4] = 4.0; printf("%f \n", f(x)); (←ここらへんがおかしいと言われます。。。) } double f(int *x) { int i; double z=0.0; for(i=0 ; i<=4 ; i++) { z += pow(0.1,*(x+i)); } return(z); }

専門家に質問してみよう