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

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

ただいまの
回答率

90.22%

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

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 671

yaaaaa

score 11

 前提・実現したいこと

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

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

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

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

 該当のソースコード

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define ROW 52
#define COL 27
#define MAX 1000

double data[ROW][COL];         //測定値格納
double b[ROW][COL];            //補完値格納

void read();
void calc(void);
void output();

int main(){
    read();
    calc();
    output();

    printf("fin\n");

    return 0;
}


void read(){              //csv読み込み&2次元配列
    FILE *fp; 
    double buf[ROW][COL];
    char *ary[COL];
    char get_read[MAX];     
    int count=0; 
    int i, j;          

    fp = fopen("rand.csv", "r");              
    if(fp == NULL){
        printf("can`t open file\n");
        return;
    }

    printf("open file\n");

    for(i=0; i<ROW; i++){
        fgets(get_read,MAX,fp);                                 
        /*文字列(char配列)をカンマで分割する*/
        ary[0] = strtok(get_read,",");                         
        for(count = 1; count < COL; count++){
            ary[count] = strtok(NULL,",");
        }
        /*文字列(char配列)をdoubleに変換する*/
        for(count = 0; count < COL; count++){
            data[i][count] = atof(ary[count]);                  
        }
    }            

    fclose(fp);  
}

void calc(void){
    int count_a, count_b;

    for(count_a=1; count_a < ROW; count_a++){                     //ROW=0とCOL=0にある数字たちは使わない
        for(count_b=1; count_b<COL; count_b++){
            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]));    //評価関数
         }
    }

    printf("calculation fin\n");
}

void output(){
    FILE *fp;
    int count_a, count_b;

    fp = fopen("test.dat", "w");                //出力ファイルの名前はここで変える
    fprintf(fp,"TITLE = \"DAM\"\n");
    fprintf(fp,"VARIABLES=\"X\",\"Y\",\"B\"\n");
    fprintf(fp,"ZONE T=\"Only Zone\", I=%d,J=%d,F=POINT\n",200,80);

    for(count_b = 1; count_b < COL; count_b++){
        for(count_a = 1; count_a < ROW; count_a++){
            fprintf(fp, "%f %f %f\n", (double)count_a/(ROW-1), (double)count_b/(COL-1), b[count_a][count_b]);    //x,y,Bで出力
        }
    }
    printf("writing now\n");
    fclose(fp); 
}

 試したこと

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

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

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/06 07:54

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

    キャンセル

  • 2018/10/06 08:02

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

    キャンセル

  • 2018/10/07 05:28

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

    キャンセル

+1

>コード内の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/07 05: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列入ってます!

    キャンセル

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

  • ただいまの回答率 90.22%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる