質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

3869閲覧

csvを読み込んでdatファイルに書き込みたいです。

yaaaaa

総合スコア17

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/10/05 14:38

前提・実現したいこと

C言語で、csvファイル(51行26列 中のデータは全て実数)を読み込んで、3列1329行のdatファイルを作成するコードを書きたい。

[コードの流れ]
1.csvファイルを読みこむ → 読み込んだデータを2次元配列に格納 
2.読み込んだ配列をもとに評価関数を作成
3.数値をdatファイルにアウトプット

発生している問題・エラーメッセージ

datファイルに書き込まれる値が所々0になってしまいます。書き込まれる値がすべて0以外の実数にしたいです。

該当のソースコード

c

1#include<stdio.h> 2#include<string.h> 3#include<stdlib.h> 4 5#define ROW 52 6#define COL 27 7#define MAX 1000 8 9double data[ROW][COL]; //測定値格納 10double b[ROW][COL]; //補完値格納 11 12void read(); 13void calc(void); 14void output(); 15 16int main(){ 17 read(); 18 calc(); 19 output(); 20 21 printf("fin\n"); 22 23 return 0; 24} 25 26 27void read(){ //csv読み込み&2次元配列 28 FILE *fp; 29 double buf[ROW][COL]; 30 char *ary[COL]; 31 char get_read[MAX]; 32 int count=0; 33 int i, j; 34 35 fp = fopen("rand.csv", "r"); 36 if(fp == NULL){ 37 printf("can`t open file\n"); 38 return; 39 } 40 41 printf("open file\n"); 42 43 for(i=0; i<ROW; i++){ 44 fgets(get_read,MAX,fp); 45 /*文字列(char配列)をカンマで分割する*/ 46 ary[0] = strtok(get_read,","); 47 for(count = 1; count < COL; count++){ 48 ary[count] = strtok(NULL,","); 49 } 50 /*文字列(char配列)をdoubleに変換する*/ 51 for(count = 0; count < COL; count++){ 52 data[i][count] = atof(ary[count]); 53 } 54 } 55 56 fclose(fp); 57} 58 59void calc(void){ 60 int count_a, count_b; 61 62 for(count_a=1; count_a < ROW; count_a++){ //ROW=0とCOL=0にある数字たちは使わない 63 for(count_b=1; count_b<COL; count_b++){ 64 b[count_a][count_b] = 0.5*( 0.5*(data[count_a][count_b] + data[count_a+1][count_b+1]) 65 + 0.5*(data[count_a][count_b+1] + data[count_a+1][count_b])); //評価関数 66 } 67 } 68 69 printf("calculation fin\n"); 70} 71 72void output(){ 73 FILE *fp; 74 int count_a, count_b; 75 76 fp = fopen("test.dat", "w"); //出力ファイルの名前はここで変える 77 fprintf(fp,"TITLE = \"DAM\"\n"); 78 fprintf(fp,"VARIABLES=\"X\",\"Y\",\"B\"\n"); 79 fprintf(fp,"ZONE T=\"Only Zone\", I=%d,J=%d,F=POINT\n",200,80); 80 81 for(count_b = 1; count_b < COL; count_b++){ 82 for(count_a = 1; count_a < ROW; count_a++){ 83 fprintf(fp, "%f %f %f\n", (double)count_a/(ROW-1), (double)count_b/(COL-1), b[count_a][count_b]); //x,y,Bで出力 84 } 85 } 86 printf("writing now\n"); 87 fclose(fp); 88} 89 90 91

試したこと

・csvを読み込むところが怪しいと思い、atofで0が返ってきてしまうのかと睨んでstrodでやってみたのですがダメでした。
・アドレスの扱いがうまくいっていないのではと考えたのですが、どこをどう確認すればいいのか分からず、お伺いを立てている次第です。

補足情報(FW/ツールのバージョンなど)

コード内のrand.csvは52行27列で乱数(0から1の間)を発生させたものでして、今はこのcsvでテストしているところです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

b[count_a][count_b] = 0.5*( 0.5*(data[count_a][count_b] + data[count_a+1][count_b+1]) + 0.5*(data[count_a][count_b+1] + data[count_a+1][count_b])); //評価関数

これ、配列オーバーしてますね


んで、Windowsでやってるなら、VisualStudioを入れでデバッグできるようにしましょう
任意の行で止めて変数のナカミを見れますぜ

投稿2018/10/05 14:46

編集2018/10/05 14:52
y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yaaaaa

2018/10/05 15:02

コードの書き方的には間違ってないけど、要素数の設定やらの関係でうまくいかない。ので、それを見るためにデバッグのやり方から勉強して、もっと詳細なエラー原因を突き止めましょう。という解釈でよろしいでしょうか?
y_waiwai

2018/10/05 22:10

いや、間違ってます 示したように、定義した配列のサイズ以上の領域をアクセスしてます で、デバッグできるようになれば、当てずっぽでコード書くようなことしなくて済みます どこでエラーしてるのか、なんでうまくいかないのか分かるようになります
y_waiwai

2018/10/05 22:54

ちょと解説しておきますと、 double arr[N]; という定義だと、N個分の配列が確保され、arr[0]からarr[N-1]までの範囲の配列となります さて、 data[count_a+1][count_b+1] という記述だと、count_a がROW-1の場合には、data[ROW]のアクセスとなり、領域がオーバーします
hichon

2018/10/05 23:02

端っこだと+1すると配列の範囲を超えた場所を参照することになります。
yaaaaa

2018/10/06 20:28

詳しい説明ありがとうございます。大変良く理解することができました。
guest

0

コード内のrand.csvは52行27列で乱数(0から1の間)を発生させたものでして、今はこのcsvでテストしているところです。

このrand.csvも提示していただけませんでしょうか。
おかしいところは、他の方も言ってますが、

b[count_a][count_b] = 0.5*( 0.5*(data[count_a][count_b] + data[count_a+1][count_b+1])
+ 0.5*(data[count_a][count_b+1] + data[count_a+1][count_b])); //評価関数
で、count_aはcount_a < ROWの範囲で変化しますが
data[count_a+1]は、最後にdata[ROW]と同じになり、ここでおかしくなります。
data[count_a][count_b+1]もdata[count_a][COL]と同じになり、ここでおかしくなります。

投稿2018/10/06 15:03

tatsu99

総合スコア5436

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yaaaaa

2018/10/06 20:42

0.377505743,0.035808239,0.666064289,0.374785161,0.27085427, 0.723936101,0.09307402,0.854294912,0.855431724,0.051270337, 0.972284517,0.659815829,0.268809991,0.60436766,0.901277836, というかんじで52行27列入ってます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問