電子書籍の厳選無料作品が豊富!

CSVファイルを読み込み構造体のメンバ、"value"に格納し、その後平均値を求めて構造体のメンバ、"ave"に格納し表示させたいのですが、読み込み格納している最中で、セグメンテーション違反で終了してしまいます。どなたかよろしければ教えて頂けないでしょうか。


プログラム
**************************************************

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 64
#define FILE_NAME_00 "f_00_01.CSV"


struct Data{
double value;
double ave;
};


int main(int argc, char *argv[]) {

FILE* fp,*fo; // ファイルポインタ用
int n, i, file_size;


struct Data *dat;

if ((fp = fopen(FILE_NAME_00,"r")) == NULL) {
printf( "file open error\n" );
exit(EXIT_FAILURE);
}


fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
dat = (struct Data*)malloc(file_size);

printf("malloc address= %p, file size= %d\n", dat, file_size);

fseek(fp, 0, SEEK_SET);
i = 0;


for(i=0;i<file_size;i++){
fscanf(fp,"%lf",&dat[i].value);
printf("%lf\n",dat[i].value);
i++;

}





fclose(fp);




printf("\n");
free(dat);

return 0;

}

***************************************************


f_00_01.CSV
***************************************************

2.313725
2.312810
2.314031
2.316167
2.315557
2.313725
.
.
.
.
.
***********************************************

A 回答 (2件)

おや、どこかで見覚えが・・・。



「for(i=0;i<file_size;i++){」ですが、fscanf()は1行読み込むところを file_size回(8倍)も余分に読んでいます。これではパソコンもたまったものではありませんよね。普通はファイルの終わりまで読むのが一般的です。
 また、無理してカンマのCSVファイルにしなくてもカンマが使われていないのですから、普通のファイル名でよいのではないですか。



#include <stdio.h>
#include <stdlib.h>
#define SIZE 64
#define FILE_NAME_00 "f_00_01.CSV"

struct Data{
double value;
double ave;
};

int main(void){
FILE* fp,*fo; // ファイルポインタ用
int n, i, file_size;
struct Data *dat;

if ((fp = fopen(FILE_NAME_00,"r")) == NULL) {
printf( "file open error\n" );
exit(EXIT_FAILURE);
}

fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
// double + double = 16バイト。 csv fileは1行8バイト。
dat = (struct Data*)malloc(2 * file_size);
printf("malloc address= %p, file size= %d\n", dat, file_size);

fseek(fp, 0, SEEK_SET);
i = 0;
while(fscanf(fp, "%lf", &dat[i].value) != EOF) {
printf("%lf\n",dat[i++].value);
}

fclose(fp);
free(dat);

return 0;
}
    • good
    • 0

読み込むファイルが別にCSV形式じゃないとかのつっこみは置いておいて、


>file_size = ftell(fp);
ファイルの末尾のファイルポインタを配列の数にするのはちょっと違うと思う。
一回ファイルの改行数をカウントして配列数を取得するか、可変長の配列を使うのが妥当かと。
>dat = (struct Data*)malloc(file_size);
やりたい処理だと以下のように修正
dat = (struct Data*)malloc(size_of(Data)*file_size);
多分、メモリ領域が足りていないでセグメンテーションエラーになっているはず。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!