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

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

ただいまの
回答率

90.62%

  • C++

    3343questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • CSV

    606questions

    CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

  • 配列

    511questions

    配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

C++でCSVファイル処理

受付中

回答 4

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,514

oohata_mk3

score 4

大学の研究で実験データをC++を使って処理しようと考えて,
実験によってデータ点数は5万点前後とまちまちなのですが,
0000や0001のように連続した番号の名前のCSVファイルをC++で1度読み込んで行数をカウントして,
カウントした行数nを配列定義の要素数に代入しようとしているのですが,
データ点数が多くなってしまったからなのか,
”segmentation foult”
と出てしまいました.
これを解決したいのですが,どのようにすればいいでしょうか?

追記
segmentation faultを解決しようとしてvectorを使ってみたのですが,
”note : template argument deduction/substitution failed :”
というエラーが出てしまいました.

#include <stdio.h>
#include <vector>
using namespace std;

int main()
{
 int nlin=0 , header=17;
 int i,cnt,c,n;
 vector<double> x1[cnt],x2[xnt],x3[cnt],x4[cnt];
 double sum1,sum2,sum3,sum4;
 double I1,I2,I3,I4;
 double I1_,I2_,I3_,I4_;
 double dt=0.0000001;
 char bff[100];
 FILE* fp;
 FILE* save;
 FILE* gp;
 char fname[]={"file[n].csv"};
 char save_fname[]={"save[n].csv"};

//file loop
for(n=0 ; n<=cnt ; n++)
{

//line count part
 fp =fopen(fname,"r");
 
 if(fp)
 {
  while(c=getc(fp)!=EOF);
   {
    if(c=='\n')cnt++;
   }
 
 }
printf("%d\n",cnt);

//return first line
 rewind(fp); nlin=0;

//file & gnuplot open for save
 save = fopen("save[n].csv","w");
  gp  = popen("gnuplot -persist","w");

//header cut part
  while(fgets(bff,100,fp)!=NULL)
 {
  if(++nlin <= header)continue;
 }

//calibration value ~ integrater
for(i=17 ; i<=2000 ; i++)
{ 
 while(fscanf(fp,"%lf%lf%lf%lf",&x1[cnt],&x2[cnt],&x3[cnt],&x4[cnt])==4)
  {
    sum1 += x1[i];
    sum2 += x2[i];
    sum3 += x3[i];
    sum4 += x4[i];
  }
}
for(i=17 ; i<=cnt ; i++)
 {
//first point at each column
    I1_= (x1[17] - sum1) * dt;
    I2_= (x2[17] - sum2) * dt;
    I3_= (x3[17] - sum3) * dt;
    I4_= (x4[17] - sum4) * dt;

//second ~ final point at 4each column
    I1 = I1_ + (x1[i+1] - sum1) * dt;
    I2 = I2_ + (x2[i+1] - sum2) * dt;
    I3 = I3_ + (x3[i+1] - sum3) * dt;
    I4 = I4_ + (x4[i+1] - sum4) * dt;
   
//writing part on file
   fprintf(save,"%f \t %f \t %f \t %f \n",I1_,I2_,I3_,I4_);
   fprintf(save,"%f \t %f \t %f \t %f \n",I1,I2,I3,I4);

   fprintf(gp,"plot %f with lines \n",I1);
   fprintf(gp,"plot %f with lines \n",I2);
   fprintf(gp,"plot %f with lines \n",I3);
   fprintf(gp,"plot %f with lines \n",I4);
  }
  

pclose(gp);
fclose(save);
fclose(fp);
}
return 0;
}

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • archiver

    2015/07/14 21:51

    ひとまず、処理させようとしているプログラムを載せていただけませんか。 その方が、より多くのアドバイスを受けられると思います。

    キャンセル

回答 4

+1

基本的なことですが

宣言部分
 int i,cnt,c,n;
 vector<double> x1[cnt],x2[xnt],x3[cnt],x4[cnt];
 
ここでエラーが出ていませんか?
まずcntが初期化されていないのでx1[cnt]の領域自体確保はおかしくなりますし、
x2[xnt]のxnt自体宣言がされていませんね(キーが隣り合っているのでcntのタイプミス??)
特にcntはmain関数の中で宣言されているのでスタック変数です。
グローバル変数であれば気の利くコンパイラならば初期値は自動的に0になっていることが多いので
うまくいけば  x1[cnt]はx1[0]の宣言になりますがスタック変数の宣言時の初期値には何が入っているかわかりません。
int宣言なので下手をすれば 負の値が入っている可能性もあります。

先ずは宣言部分から見直されたらいかがでしょうか

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

質問の内容から言えるのは、メモリも配列サイズも有限だ。ということです。
segmentation fault はプログラム実行中に予定の利用範囲を超えちゃったよ、というお知らせなので、有限の資源で切り盛りする考え方を持つ必要があります。
また、C言語はfail-safeも原始的なので、スクリプト言語のようによろしくやって貰おうと思っているとメモリ周りでつまづき易いです。

下記の辺りを確認してください。

・配列サイズを必要充分に確保しているか。
・意図しない配列範囲にアクセスしていないか。
・利用可能なメモリ量に対して、読み込んでいるデータサイズが大きすぎないか。
・動的に確保したメモリがある場合にきちんとリリースできているか。

下記は考える範囲を絞ったり、全部自分で書かずに他にお任せする場合の補足です。

・CSVの読み込みを一括で行っている場合、実行速度は落ちるが一旦行単位にして動作を確認する。
・iostreamや動的配列(std::vectorなど)を使う。
・行数をカウントするだけで良い場合、既存の行数を出力してくれるプログラム(linuxのwcコマンドとか)を呼び出して、結果だけ集める処理を書く。


segmentation faultについては簡単にまとめている方がいらっしゃいましたので、参考までに。
ttp://minus9d.hatenablog.com/entry/20140121/1390314231

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/07/15 00:34 編集

    コード拝見しました。

    ・ハードコードは極力避けた方が後で混乱せずに済みます。
    ・std::vector は push_backで要素を動的に増やせます。わざわざ予め要素数を決め込まない方が良いように思います。(処理する個数が固定なら決め込んでも実害ないかもしれません)
    ・forループで i=17; i < 2000; .. となっている部分などは、ヘッダー17行を削るなら必要ないように思います。vectorに必要な分を格納してあれば、必要回数反復処理するだけです。反復処理にはイテレータも活用しましょう。

    …と、ここまで書いておいてこんなことを書くのは微妙かもしれませんが、この処理を書くのでしたら、まずはC++よりスクリプト言語の利用をお勧めします。(敢えてC++の勉強で書かれているようでしたら、読み流してください。)
    ※個人的には、Pythonなどが良いかと思います。
    スクリプトで書いてみて、あまりにも処理が重い、データ処理的にメモリ操作が面倒、やたらにビット操作が必要…という話が出てきたらCで書いてみる。という選択の仕方もあると思います。

    キャンセル

0

環境が分からないのでなんともいえないのですが・・・
配列はどのような構造になっていますか? 構造体の配列? ただの整数の配列?

”segmentation foult” が起こっているとすれば、配列の要素数が足りない可能性があります。
(配列にデータを入れようとしたが、そこは確保された領域外だった・・・とか)

64ビットのWindowsなら1Gぐらい確保しても問題ないですよd^^
再度、確保する領域とデータ数が合ってるかどうか確認されたらどうでしょう?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/07/15 00:25 編集

    行数を数える部分ですが
    if(fp)がNGの処理が抜けているようです。また、while(c=getc(fp)!=EOF);では、下のブロックに入ったときにcにはEOFが入っています。(;が余計です)
    あと、getline()を使われたらいかがでしょうか?
    1文字ずつ読み込むより早いですよd^^
    また、fscanf()よりもgetline()で1行読み込んでsscsnf()を使ったほうが安全です。

    キャンセル

0

 vector<double> x1[cnt], ...
これだとx1の型がvector<double>[]
(double型を格納するvectorクラスの配列,要するに二次元配列)になってしまいます。
後のコードを見る限りこれは意図通りではないと思います。
vector<T>[]を意図して使う場合はこんな感じになります。
int main(void){
    vector<int> x[2]; //vector<int>が格納された配列を生成
    x[0].push_back(1); //[0]のほうのvector<int>の末尾に1を追加
    cout <<x[0][0]<<endl; // "1"
}

一次元ならこうです:
 vector<double> x1, ...

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

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

関連した質問

同じタグがついた質問を見る

  • C++

    3343questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • CSV

    606questions

    CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

  • 配列

    511questions

    配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。