• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:fscanfの書式について)

C言語でのファイル読み込み方法についての質問

このQ&Aのポイント
  • C言語で特定の形式のファイルを読み込む方法について質問です。具体的には、a[n][n]という形式で並んでいるファイルをどのように読み込むかが知りたいです。
  • Fortranには、DOループを使って特定の形式のファイルを読み込む方法がありますが、C言語ではどのように書けばいいのか分からないです。
  • 現在、C言語を初めて学んでおり、Fortranの経験がありますが、C言語のファイル読み込み方法が分からないです。改行の問題もあります。

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

  • ベストアンサー
回答No.1

取得するデータの数が不定だったり、多過ぎる場合はfscanfを用いるのは妥当ではありません。 fgets等で1行全体を読み込んだ上で、個々のデータを区切って取得していくのが妥当でしょう。 データが「,」区切りなら「,」をセパレータとしてstrtokなどを用いて個々のデータを取り出して行きます。 double a[n][n]; char buf[1024]; int i, j; char *datp; i = 0; while (fgets(buf, 1024, fp) != NULL) { j = 0; while(1) { if (j == 0) { datp = strtok(buf, ","); } else { datp = strtok(NULL, ","); } if (datp == NULL) { break; } a[i][j] = atof(datp); j++; } i++; }

knock123
質問者

お礼

出来ました!! フォートランに比べて長いのが難点ですが。 ちなみに、私がもっているC言語の解説本、柴田著の明解C言語入門編と中級編にはなんとstrtokが載っていませんでした…。もっとちゃんとした本を買わないといけないですね。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (4)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.5

test.txt----- 1,2,3, 11,12,13, 21,22,23, ------------- test.c------- #include <stdio.h> #define n 1 int main(){ float a[n+2][n+2] ; int i,j ; FILE* fp ; fp = fopen("test.txt","r"); if ( fp == NULL ) { fprintf( stderr, "File Open Error\n" ); return 1 ; } for(i=0;i<=n+1;i++){ for(j=0;j<=n+1;j++){ if ( 1 != fscanf(fp,"%f %*[,] ",&a[i][j]) ) { fprintf( stderr, "Error\n" ); return 1; } } } fclose(fp) ; for(i=0;i<=n+1;i++){ for(j=0;j<=n+1;j++){ printf( "%7.2f,", a[i][j] ); } printf( "\n"); } return 0; } ------------- 実行結果:スペースを_に置き換えてあります ___1.00,___2.00,___3.00, __11.00,__12.00,__13.00, __21.00,__22.00,__23.00, ------------- と、こちらではまったく問題ありませんが。 やりそうな間違いとしては、aをdouble型の配列で宣言している、というのがあります。 補足等もaの大きさは書いてあるのですが、型が書いてないのが気になります。 scanfの変換指定子と変数の型は一致している必要があります。 %fはfloatへのポインタを要求します。他のポインタを入れてもfloatへのポインタだと勝手に解釈します。 doubleとfloatでは内部表現が違うので、doubleの領域にfloatの内部表現が書き込まれても、数値としてはまったく別のものになります。 aの型をfloatにするか、fscanf(fp,"%lf %*[,] ",&a[i][j]) とdouble型を要求する lfを使用するかです。 floatを使う積極的な理由がなければ、後者をお勧めします。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

「だめ」というときには, 「どう」ダメなのかをちゃんと書いてほしい. あと, fgets や strtok にもそれなりに「くせ」があるので, きわどい状況だといろいろ困難があったりします.

全文を見る
すると、全ての回答が全文表示されます。
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

まずは、マニュアルをよく読むことです。 fscanfのマニュアルには、フォーマット文字列の書式について詳しくかかれています。 その前に > a[n][n]が、 > a11,a12,a13---a1n, とありますが、 a[n][n]はどのような変数宣言していますか? Cでは float a[n][n] ; と宣言すると a[0][0]~a[n-1][n-1]のn×n個の配列が用意されます。0から始まることと、「0からn個の整数」はn-1になることは、よく間違える点なので注意してください。 > a11,a12,a13---a1n, というデータを入れる際には、 ・a[1-1][1-1] = a11, a[1-1][2-1]=a12 .... とCの配列に添字を合せる方法と ・float a[n+1][n+1] ;と宣言しておいて a[1][1]=a11, a[1][2]=a12.... と1から始めて、0を使わない方法があります。 どちらにするかは、設計段階で決めておいてください。 以下の例では、0から始まるものを使用します。 さて >for(i=0;i<=n+1;i++){ >for(j=0;j<=n+1;j++){ このループでは、 i,jそれぞれ、0からn+1の n+2 回ループします。 > a11,a12,a13---a1n, この例示が正しいなら、n行n列のデータですから、行も列も2つも多いです。 Cでは、配列の添字が正しいかどうかを『確認しません』。 [n-1]までの配列に[n+1]を入れても、何事もなかったように、コンパイルが成功します。 しかし、大抵は実行時に誤動作を起こし、致命的なエラーになることがあります。 むしろ、エラーになるだけましで、『正常に終了』したかに見えることもあります。 この場合では、ループは for(i=0;i<n;i++){ for(j=0;j<n;j++){ です。この書き方はCではよく見掛けます。 あるいは、FortranのDOループを意識するなら for(i=0;i<=nー1;i++){ for(j=0;j<=nー1;j++){ です > fscanf(fp,"%f7.6 %1s ",&a[i][j],kama); 書式の基本形は %[最大フィールド幅(省略可能)][修飾文字(省略可能)]変換指定文字 です。 これと空白文字以外は「書かれた通りの文字列に一致するパターン」となります。 そこで、この文を見ると %f : floatへのポインタを要求。小数点付きの数字列をfloat型の数値に変換 空白: 0個以上の空白文字 7.6: 「書かれたままの『7.6』という文字列に一致」 空白: 0個以上の空白文字 %1s: charへのポインタを要求。最大1文字の空白でない文字列を、charへのポインタから始まる領域に終端文字'\0'付きで読み込み という書式になっています。 ・%f7.6は %7.6fのつもりなのでしょうが、数値を読み込むなら%fだけで十分です。 小数点以下の数字にはそもそも対応していません。 #ついでに。 printfでは%7.6fとして小数点以下の桁数を指定できます(この場合6桁)が、その前のフィールド幅は #整数部:少なくとも1桁 #小数点:一桁 #を含むため、最低でも8桁必要であり、7と指定しても意味がありません。 ・%1sでカンマを取り込んでいるのでしょう。これは > a11,a12,a13---a1n, と、行末にも必ずカンマが付いているときには有効ですが、もし、カンマが無いと、次の行の先頭の「文字列の先頭1文字」(おそらく a21の最上位の数字か正負の符号)が「カンマのかわり」の取り込まれてしまいます。 確実にカンマを取り込むなら %[,] が使えますし、カンマ無し改行するのなら %[,\n] としてカンマか改行を取り込むようにするのがよいです。 また、取り込んでも使わないのでしょうから、「ただ読むだけ」の*を使って%*[,] %*[,\n] とすると、KAMAなどとダミーの変数を用意する必要もありません。 あと書かれていませんが、 KAMAの宣言はどうなってますか? Cでは文字列は charの配列を使い、必ず終端文字'\n'で終わります。つまり、1文字の文字列を入れるには char KAMA[2]と終端文字の分も含めた大きさにする必要があります。 あと、fscanfを使ったら、戻り値でエラーが無かったかどうかを確認することを強くお勧めします。

knock123
質問者

補足

丁寧にありがとうございます。 宣言はa[n+2][n+2],KAMAはKAMA[2]で宣言しています。混乱させてすみません。正しくは a00,a02,a03---a0n+1, a10,----------a1n+1, . . an+10,----------an+1n+1, 配列には必ずカンマが付いています。 N=1の時、例えば以下の様な形です。 Nは実際には100~5000の間の整数です。この数字データをaに読み込みたいという感じです。 1.0,2.0,3.0, 1.0,2.0,3.0, 1.0,2.0,3.0, (数字とカンマの間にスペースはありません) お話をまとめると、以下でこれで良いのかな?と思えたのですが、 これでも駄目です。私は何を誤解しているのでしょうか? for(i=0;i<=n+1;i++){ for(j=0;j<=n+1;j++){ fscanf(fp,"%f %*[,] ",&a[i][j]); } } ご教授下さい。どうぞよろしくお願いいたします。

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

kama って何のことだろうと思ったら、 comma のことだったんですね。 腑に落ちてよかった。

knock123
質問者

補足

すいません。 人に見せるプログラムで無いので、日英ごっちゃで短くなる配列名を付けてます。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • fscanfについて

    ファイルの中身が例えば 600 0.6 3.5 となっているとき, fscanfで読み込むと改行\nを読み込んでくれる場合と読み込まない場合がありませんか? また,これだったら,経験から fscanf(fp,"%d",&a); fscanf(fp,"%f",&b); fscanf(fp,"%c",&c); // \nの読み飛ばし fscanf(fp,"%f",&d); fscanf(fp,"%c",&e); // \nの読み飛ばし でやるとできそうですが,fscanf(fp,"%d",&a);のあとの\nの読み飛ばしがいらないのは何故ですか?

  • fscanfについて質問です。

    さっそく質問させていただきます。 fscanfで、どうしても納得いかないことがあります。 どのように説明して良いのか分からないのでソースを書きます。 (説明用にアレンジ) ------------------------------------------------------ double a[10000][10]    // この程度のサイズの配列 for(i=0;i<10000;i++){   for(j=0;j<10;j++){     // これでは実行時エラー(i=0,j=0の時)     fscanf(fp,"%lf",&a[i][j]);     // これならOK     double buffer;     fscanf(fp, "%lf", &buffer);     a[i][j] = buffer;   } } ------------------------------------------------------ なぜこのようになるのか理由がわかりません。 もしご存知の方がいらっしゃいましたら、 ぜひ教えていただきたいのですが。 私はWINDOWS2000&VC++6を使っております。 よろしくお願いします。

  • FortranにあってCにない関数?について

    10年間Fortran90でプログラミングをしてきましたが、 C言語を使う必要があって、プログラムを書き直し中の者です。 入門書を数冊読んでいて疑問に思ったのですが、Fortranには、 A=SUM(B) と書けば、配列Bの全ての総和をAに返す、という関数があるのですが、C言語に同じような関数はないのでしょうか?(標準ライブラリに無いという事はないのでしょうか?) Fortranと比べてCは組み込み関数が少ないという印象を持ったのですが実際そうなのでしょうか? また、Fortanでは配列の和をとる時、 do i=0,n a(i)=b(i)+c(i) end do を一行で、 a(0:n)=b(0:n)+c(0:n) と書いても良いですし、もし定義されている全部の配列の要素が対象なら a=b+c と一行で書いても良いのですが、c言語では似たような書き方はできないのでしょうか? つまり、多次元配列を扱う時、Fortranでは単に「a=b+c」と書けば済むところを、Cでは for (i=0,i<=n,i++){ for (j=0,j<=n,j++){ for (k=0,k<=n,k++){ a[i][j][k]=b[i][j][k]+c[i][j][k]; }}} と書かなくてはいけないのか?と悩んでおります。 私がCの機能を知らないだけなのか、Cとはそうゆうことが出来ないのか、浅学なため判断できません。 ご教授ください、どうぞよろしくお願いいたします。

  • FORTRAN→Cに翻訳

     どなたか、次のFORTRANのプログラムを、Cに、翻訳して頂けないでしょうか。C++ではなく、Cです。ANSI準拠のCでお願いします。  プログラムの内容は、最小二乗法による計算プログラムです。MS-DOS Ver3.3~6.0の頃の、MS FORTRANコンパイラ仕様のものです。その頃持っていたFORTRANの本も処分してしまい、今からFORTRANを学びなおすのにも多大な労力と時間がかかりそうなので、Cに翻訳して頂ければ大変ありがたいです。よろしくお願いします。 (“□”はタブ) ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆ C□LEAST SQUARE APPROXIMATION □PROGRAM MAIN9 □DIMENSION X(100),Y(100),S(0:18),T(0:9),SM(10,10),TV(10),AV(10) □WRITE(*,*) 'N ?' □READ(*,*) N □WRITE(*,*) 'x1,x2,..,xn ?' □READ(*,*) ( X(I),I=1,N ) □WRITE(*,*) 'y1,y2,..,yn ?' □READ(*,*) ( Y(I),I=1,N ) □WRITE(*,*) 'M ?' □READ(*,*) M □DO 110 K=0,M*2 □□VS=0. □□DO 100 I=1,N □100□VS=VS+X(I)**K □□S(K)=VS □110□CONTINUE □□DO 130 K=0,M □□□VS=0. □□□DO 120 I=1,N □120□VS=VS+Y(I)*X(I)**K □□□T(K)=VS □130 CONTINUE □□DO 140 I=1,M+1 □□□DO 140 J=1,M+1 □□□□K=I+J-2 □□□□SM(I,J)=S(K) □140 CONTINUE □□DO 150 I=1,M+1 □150 TV(I)=T(I-1) □□CALL SIMULE( AV, SM, TV, M+1 ) □□DO 160 I=1,M+1 □160 WRITE(*,1000) I-1,AV(I) □1000 FORMAT(1H ,'A',I1,'=',F10.5) □□STOP □□END ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆

  • doubleからfloatにすると表示が変になる

    しょうもない質問ですいません。 下記のC言語の行列積のコードでは行列の変数をdoubleとしていますが、これをfloatに全て置き換えると、printfで表示させる結果がバグってしまいます。 原因は何でしょうか? 最近ひさしぶりにC言語を触ったので、しょうもないところでつまずきました。 お願いします。 ----------------------------------------- #include <stdio.h> #include <stdlib.h> #define N 10 //N次の正方行列まで扱えるようにする void matrixmultiply(int n,double a[N][N],double b[N][N],double c[N][N]); int main(int argc, char** argv) { int i,j,n; double A[N][N],B[N][N],C[N][N]; FILE *readin1,*readin2; /*行列の値が書き込まれたファイルを開く*/ if((readin1=fopen("a.dat","r"))==NULL) { printf("a.datを開けません\n"); exit(1); } if((readin2=fopen("b.dat","r"))==NULL) { printf("b.datを開けません\n"); exit(1); } printf("行列の次数を入力してください\n"); scanf("%d",&n); printf("%d次の正方行列の掛け算を行います\n\n",n); /*ファイルから数値を読み込み、配列に代入する*/ for(i=0;i<n;i++) { for(j=0;j<n;j++) { fscanf(readin1,"%lf",&A[i][j]); fscanf(readin2,"%lf",&B[i][j]); } } matrixmultiply(n,A,B,C); //関数を呼び出し行列の掛け算を行う。 /*結果を表示する*/ printf("計算結果\n"); for(i=0;i<n;i++) { for(j=0;j<n;j++) { printf("%lf ",C[i][j]); } printf("\n"); } fclose(readin1); fclose(readin2); return 0; } /*掛け算を行う行列2つと、結果を入れる行列を引数として受け取る。*/ void matrixmultiply(int n,double a[N][N],double b[N][N],double c[N][N]) { int i,j,k; /*受け取った2つの行列の掛け算を行う。*/ for(i=0;i<n;i++) { for(j=0;j<n;j++) { for(k=0;k<n;k++) { c[i][j]+=a[i][k]*b[k][j]; } } } }

  • 行列の積について

    3行3列の行列AとB、およびその和と積を表示するものです #include <stdio.h> int main (void) { int i,j,k; double a[3][3] = {{2.4, 5.5, -8.5},{0.8, 3.7, 1.1},{3.5, -9.1, 2.6}}; double b[3][3] = {{-5.1, 9.8, 2.3},{-4.1, 0.2, -0.3},{3.3, 6.1, -1.3}}; double c[3][3] = {0}; printf(" 行列A\n"); for (i = 0; i < 3; i++){ for (j = 0; j < 3; j++) printf("%5.1f", a[i][j]); printf("\n"); } printf("\n 行列B\n"); for (i = 0; i < 3; i++){ for (j = 0; j < 3; j++) printf("%5.1f", b[i][j]); printf("\n"); } printf("\n 行列A+B\n"); for (i = 0; i < 3; i++){ for (j = 0; j < 3; j++) c[i][j] = a[i][j] + b[i][j]; } for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) printf("%5.1f", c[i][j]); printf("\n"); } for (i=0; i<3 ; i++){ for (j=0; j<3; j++) for (k=0; k<3; k++) c[i][j] =c[i][j]+ a[i][k]* b[k][j]; } printf("\n 行列AB\n"); for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) printf("%7.2f", c[i][j]); printf("\n"); } return 0; } これだと積だけが異なった値が出てしまいます。 試しに、積の部分だけで組んでみると正しい答えが出ました。 for文のブロックの組み方がまずいのかなと思っていますが、これ以外だと、行列のレイアウトが崩れてしまいます どのように直したらいいのか、ご教示お願いします

  • fortran errorについて

    fortranを勉強していたのですがエラーがでてしまい、何時間かけても理解できなかったので質問させてください。 以下プログラム program test !ここからメインルーチン !前準備 配列の用意 implicit none integer N integer,dimension(0:N,0:N) :: A integer :: i,j,k read * ,N !初期状態の代入 do i=0,N do j=0,N A(i,j)=0 end do end do do i=N/2,N-1 A(N/2,i)=1 end do do i=N/2,N-1 A(N/2+1,i)=-1 end do !ループ 50回ループさせる do k=0,50 !状態の表示 call visualize !サブルーチン visualize subroutine visualize do i=0,N do j=0,N if(A(i,j)== 1) write(*,'(A1)',advance='NO') "*" if(A(i,j)== 0) write(*,'(A1)',advance='NO') " " if(A(i,j)==-1) write(*,'(A1)',advance='NO') "+" end do write(*,*) end do !end subroutine visualize call insert !サブルーチン insert subroutine insert do i=0,N do j=0,N if(A(i,j)== 1) A(i,j)=-1 if(A(i,j)== 0) A(i,j)=max(0,A(i-1,j),A(i,j-1),A(i,j+1),A(i+1,j)) if(A(i,j)==-1) A(i,j)=0 end do end do !end subroutine insert end do end program test これでコンパイラすると In file test.f90:48 subroutine visualize 1 Error: Unclassifiable statement at (1) In file test.f90:69 subroutine insert 1 Error: Unclassifiable statement at (1) とでます いろいろ調べたのですが全くわかりませんでした できればよろしくお願いします

  • 何処の会社のBASICか教えて下さい。

    何処の会社のBASICか教えて下さい。 下記のようなソースファイルです。 宜しくお願いします。 DIMENSION EBK(20,20),ECK(20,20),SH(20),SL(20),CRM(20,20), 1CLM(20,20),Q(20),SOM(20),CDM(20,20),CUM(20,20),BML(20,20), 2BMR(20,20),BMU(20,20),BMD(20,20),DVL(20,20),DVR(20,20),DVU(20,20), 3DVD(20,20),RVU(20,20),RVD(20,20),TML(20,20),TMR(20,20), 4TMD(20,20),TMU(20,20),RMD(20,20),RMU(20,20),BBML(20,20), 5BBMR(20,20),BBMD(20,20),BBMU(20,20),TQL(20,20),TQR(20,20), 6TMQ(20,20),QLL(20,20),QLR(20,20),CMM(20,20),TMM(20,20) READ(5,10) M,L READ(5,10) N1,L1 N12=Nl+2 N13=N1+1 L12=Ll+2 L13=L1+1 10 FORMAT(2I5) DO 15 I=1,N12 DO 15 J=1,L12 EBK(I,J)=0.0 ECK(I,J)=0.0 15 CONTINUE READ(5,11)((EBK(I,J),J=2,L13),I=2,N12) READ(5,11)((ECK(I,J),J=2,L12),I=2,N13) 11 FORMAT(7F10.2) READ(5,11)(SH(I),I=2,N13) READ(5,11)(SL(I),I=2,L13) IF(L-1)20,30,30 20 DO 21 I=2,N12 DO 21 J=1,L12 READ(5,12)CLM(I,J),CRM(I,J),CMM(I,J),QLL(I,J),QLR(I,J) 21 CONTINUE 12 FORMAT(5F10.2) DO 40 I=2,N12 DO 40 J=1,L12 CLM(I,J)=-CRM(I,J) 40 CONTINUE

  • fortranプログラムについての質問です。

    fortranプログラムについての次の問題について質問させてください。 i=1、2、・・・、50に対し(i,a500(i))(i,a2000(i))を次の演算に従い計算せよという問題です。わかりにくいですが 500と2000、さらに次の式のaのあとのnやn+1,n-1などは添字です。 an+1(i)=0.5{an(i+1)+an(i-1)-2.0d0an(i)}+an(i)  (i=2,3,・・・49), (n=1,2,・・・,500,・・・,2000) ただしa1(i)=0.0(i=1,2,・・・,49), a1(50)=1.0, an(1)=0.0, an(50)=1.0 (n=1,2,3,・・・,500,・・・,2000) である。 というものです。自分は添字のnなどについてはプログラム上では無視し、一次元配列aとbを宣言して、「DOループも用いて i=1~49を回してまずa2(これがb)を求め、そのa2(すなわち)を元の漸化式にの右辺に結果を入れ、それを500回と2000回 別々に回す」という操作を考えたのですがうまくいきません。i-1やi+1をどう扱うかや、そもそもこの考え方は合っているのか、 どうするほうが良いのかなどについてアドバイスをいただきたいです。よろしくお願いします。

  • 実フーリエ係数an,bnをC言語を使って求める問題について質問です。

    実フーリエ係数an,bnをC言語を使って求める問題について質問です。 自分の考え方のどこが違うのか指摘していただけたら幸いです。 係数を求める式は、 an = 1/π ∫[0..2π]f(x)cos(nx)dx ...1式 bn = 1/π ∫[0..2π]f(x)cos(nx)dx ...2式 まず、1式のanについて考えます。 扱うデータ数をN、データとデータの間隔をΔxとし、上のanの式を離散化すると、 an = 1/π シグマ[x=0..N-1]f(x)cos(n*2π*x/N)Δx ...3式 ここで、f(x)=cosx, N=4, Δx=π/2, f(0)=1,f(1)=0,f(2)=-1,f(3)=0 を与えると3式は以下のようになる。 an = (1/π)*(π/2) シグマ[x=0..3]f(x)cos(n*2π*x/4) = 1/2 シグマ[x=0..3]f(x)cos(n*π*x/2) ...4式 同様に bn = 1/2 シグマ[x=0..3]f(x)sin(n*π*x/2) ...5式 4,5式を用いて、実フーリエ係数an,bnを求めるプログラムを作成する。 (今回は表示はanのみとする) ----------------------------------------------------------------------------- #include <stdio.h> #include <math.h> #define PI 3.1414926434897//円周率 int main(){ int i,j; int num=4;//データ数 double an[4],bn[4];//フーリエ実係数an,bn double data[4]={1,0,-1,0};//扱うデータ //初期化 for(i=0; i<num;i++){ an[i]=0; bn[i]=0; } //フーリエ変換 for(i=0; i<num; i++){ for(j=0; j<num; j++){ an[i] += data[j]*cos((2*PI*i*j)/num); bn[i] += data[j]*sin((2*PI*i*j)/num); } an[i] /= 2; bn[i] /= 2; } //実フーリエ係数anを表示 for(i=0; i<num; i++){ printf("a[%d]%lf\n",i,an[i]); } return 0; } ----------------------------------------------------------------------------- 実行結果は、以下のようにanを表示します。 a[0]0.000000 a[1]1.000000 a[2]0.000000 a[3]1.000000 フーリエ級数の考え方から、ある関数F(x)は、 F(x) = a0/2 + シグマ[n=1~∞](ancos(nx) + bnsin(nx)) ...6式 のようにcosとsinの波の合成で表すことができます。 今回は関数f(x)=cosx(データ数4)に対してフーリエ変換を行ったため、cosxの成分だけが残る。 つまりn=1のときのA1が1となり、他の成分A0,A2,A3は0になると思うのですが、実行結果のa[3]の出力も1となってしまっています。 どこに原因があるのか分からなくて困っているのでアドバイスよろしくお願いします。