講義の課題でガウスの消去法を実装した過程で、係数の情報をテキストファイルから取得する必要があった。
いろんな人が使いそうなのでまとめます。
もっと良いやり方が必ずあると思うので、まあ動く、ぐらいのものだと思って見てください。
テキストデータはこんな感じ
3 4 2 1
5 4 7 2
2 1 4 8
3x_1 + 4x_2 + 2x_3 = 1
・・・・・・・・
みたいなイメージですね
ソースコードです
main.c
//aはm*mの係数情報,bは定数項の情報
double **a,*b;
int main(void){
int i;
int countData = 0;
FILE *fp;
char fname[50]; // ファイル名の取得
int c;
// ファイル名の入力・ファイルオープン
scanf("%s",fname);
fp = fopen(fname, "r");
//格納されてない時
if ((fp = fopen(fname, "r")) == NULL) {
fprintf(stderr, "%s\n", "error: can't read file.");
return EXIT_FAILURE;
}
// ファイル名が変数fnameに格納されている場合
//行数カウント
while((c = fgetc(fp)) != EOF) {
if(c == '\n') countData++;
}
//fgetc使うとなぜかfscanfをしても0しか入らないので一旦fcloseしてopenし直す、ここは本当にわからなかった
fclose(fp);
if ((fp = fopen(fname, "r")) == NULL) {
fprintf(stderr, "%s\n", "error: can't read file.");
return EXIT_FAILURE;
}
printf("countData = %d\n",countData );
//動的にメモリを確保
a = malloc(sizeof(double) * countData);
for(i=0;i<countData;i++){
a[i] = malloc(sizeof(double) * countData);
}
b = (double *)malloc(sizeof(double) * countData);
// ファイル内のデータを取得する
for(i=0;i<countData;i++){
for(n=0;n<=countData;n++){
if(n<countData) fscanf(fp,"%lf",&a[i][n]);
else fscanf(fp,"%lf",&b[i]);
}
}
/*fscanfが正しく機能しているか確認
for ( i = 0; i < countData; i++ ) {
printf("%.2f, %.2f, %.2f, %.2f\n", a[i][0], a[i][1], a[i][2] b[i]);
}*/
}
fgetcで行数取得してそれをcountDataとして、その分だけメモリを確保してます。
fgetcを使うとfscanfがうまくいかない(全部値が0になった)のは本当に謎でした。謎は解決してません。
応急処置で一旦fcloseしてまたfopenするという、、、
誰かの参考になれば嬉しいです。
それにしてもガウスの消去法実装するの思ったよりもきつかった、、、難しいです。