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

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

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

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

Q&A

解決済

3回答

4970閲覧

C++でcsvを2次元配列に格納

Kinsho

総合スコア18

C

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

0グッド

0クリップ

投稿2020/09/05 11:44

編集2020/09/05 12:01
#include <iostream> #include <string> #include <stdint.h> #include <vector> #include <stdio.h> #include <stdlib.h> #include <cmath> #include <iostream> #include <math.h> #include <fstream> #include <sstream> #include <algorithm> #include <chrono> #include <utility> #include <time.h> #include <tuple> #include <cstdint> #include <cstdio> #include <random> int main() { ifstream streamx("Bx.csv"); string linex; double Br[364][184]; const string delim = ","; int rowx = 0; int colx; while (getline(streamx, linex)) { colx = 0; for (string::size_type spos, epos = 0; (spos = linex.find_first_not_of(delim, epos)) != string::npos;) { string token = linex.substr(spos, (epos = linex.find_first_of(delim, spos)) - spos); Br[rowx][colx++] = stod(token); } ++rowx; } cout << Br[4][57];//読み込めたかのチェック return 0; } ```### 前提・実現したいこと C++でのcsvファイル読み込みについて質問です. 読み込みcsvファイルの情報をdouble型の2次元配列に格納したいですが,ネットでいろいろ調べたり自分でコードを作ってみてもabort()has been calledなどいくつかエラーが表示されてしまい先に進めません. Bx.csvという364*184のcsv形式ファイルをBr[364][184]という配列に入れたいと考えています. 質問前に散々調べましたがプログラミング初心者でして今現在の力では対応できませんでした. また同規模のcsvを一度に20枚ほど読み込む必要があるのですがその際に変更すべき個所なども教えていただけますと幸いです. 何卒ご教示お願いします. ### 発生している問題・エラーメッセージ エラーメッセージ debug error! abort() has been called ### 試したこと 以下の部分をmain関数の一部分に突っ込んでおり,これをコメントアウトすればプログラムは正常に動くので以上はこの部分だけだと思います.またCPUのメモリ容量の問題かと思いましたが,研究室の大きな計算機に放り込んでも同様のエラーを返されたので(そもそもそこまで大きなデータではないですし)それも無関係だと思います. ### 補足情報(FW/ツールのバージョンなど) visual studio 2015/2019/g++は最新版にアップデートしてあります.

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

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

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

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

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

BeatStar

2020/09/05 11:49

コードは『編集時の』、"<コード>" または "<code>" となっているものを押してからその中に書いた方がいいですよ。読みづらいですし。
cateye

2020/09/05 11:52 編集

コードは、コンパイル出来る状態て上げて下さい。
Kinsho

2020/09/05 12:02

変更したしました.このサービスを使うのが今回初めてのため不慣れですみません.
cateye

2020/09/05 12:09

ヘッダファイルにCのヘッダ(〜.h)が入っているのは何故でしょう?
Kinsho

2020/09/05 12:16

csv読み込みでいろいろ検索していた時にいろいろincludeした残りですね.元のコードの他の部分を見てもおそらく使っていなさそうなので無視していただいて大丈夫です.
guest

回答3

0

提示されたコードの問題点は、Bx.csvが想定している列数(184)や行数(364)を超えていることをチェックせずに、読み込んだデータを配列の要素に代入していることです。つまり、rowxcolxの値が2次元配列のそれぞれの要素数以上の値になっても、Br[rowx][colx++] = stod(token);で値を設定してしまいます。

試しに、for文の継続条件を

C++

1rowx < 184 && colx < 364 && 2 (spos = linex.find_first_not_of(delim, epos)) != std::string::npos

に変更してみてください。

これでエラーが出ないのであれば、読み込んでいるCSVファイルの内容が「364*184のcsv形式」ではないということなので、CSVファイルの行数や列数をチェックしてください。

投稿2020/09/05 12:21

Daregada

総合スコア11990

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

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

Kinsho

2020/09/06 01:27

ありがとうございます.解決できました.
guest

0

Br[rowx][colx++] = stod(token); の直前に
cout << "rowx = " << rowx << ", colx = " << colx << ", token = [" << token << "]\n";
をいれて、どこでおかしくなっているか見ましょう。

投稿2020/09/05 18:38

編集2020/09/06 00:28
kazuma-s

総合スコア8224

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

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

Kinsho

2020/09/06 01:23

ありがとうございます!この通り実行したら rowx = 0, colx = 0, token = [・ソ0] と出てきて普通のcsvではなくUTF-8(BOM付き)担っていたことに気づくことができました.
guest

0

ベストアンサー

std::getline() のオーバーロード関数に区切り文字まで読み込めるバージョンがあるので、それを使ったほうがカンマ区切りの文字列を解析するのが楽なのではないでしょうか。

getline - cpprefjp C++日本語リファレンス

cpp

1#include <fstream> 2#include <iostream> 3#include <sstream> 4#include <string> 5#include <vector> 6 7using Mat = std::vector<std::vector<double>>; 8 9/** 10 * @brief 1行分パースする。 11 * 12 * @param line 行 13 * @param delim 区切り文字 14 * @return std::vector<double> 値の一覧 15 */ 16std::vector<double> parse_line(const std::string &line, char delim = ',') 17{ 18 std::vector<double> values; 19 20 std::istringstream ss(line); 21 std::string token; 22 while (std::getline(ss, token, delim)) 23 values.push_back(std::stod(token)); 24 25 return values; 26} 27 28/** 29 * @brief CSV を解析する。 30 * 31 * @param path CSV ファイルのパス 32 * @return Mat 行列 33 */ 34Mat parse_csv(const std::string &path) 35{ 36 Mat mat; 37 38 std::ifstream ifs(path); 39 if (!ifs) { 40 std::cout << "Failed to open csv path" << std::endl; 41 return mat; 42 } 43 std::string line; 44 45 while (std::getline(ifs, line)) { 46 // 1行分解析する。 47 std::vector<double> values = parse_line(line); 48 mat.push_back(values); 49 } 50 51 return mat; 52} 53 54int main(int, char **) 55{ 56 Mat mat; 57 try { 58 mat = parse_csv("sample.csv"); 59 } catch (std::exception &e) { 60 std::cout << "Error: " << e.what() << std::endl; 61 return 1; 62 } 63 64 // 出力する。 65 if (!mat.empty()) { 66 std::cout << "matrix size: " << mat.size() << "x" << mat.front().size() << std::endl; 67 68 for (auto row : mat) { 69 for (auto x : row) 70 std::cout << x << " "; 71 std::cout << std::endl; 72 } 73 } 74}

投稿2020/09/05 12:11

編集2020/09/05 13:02
tiitoi

総合スコア21956

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

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

Kinsho

2020/09/05 12:24

こちらを使ってみても debug error! abort() has been called. と表示されてしまいます. 問題はプログラムではなくcsvの方でしょうか?
tiitoi

2020/09/05 12:26

例外キャッチするようにコードを修正したので、なにか表示されたら教えて下さい
Kinsho

2020/09/05 12:54

一応コンパイルはできるようになりました! ただ 実行環境の冒頭にError:invalid stod augumentと出てしまい, さらに別枠に Debug Assertion Failed! Program: C:YWINDOWS ¥SYSTEM32¥MSVCP140D.dll File: CXprogram files (x86)¥microsoft visual studio 14.07vc¥include¥vector Line: 1234 Expression: vector subscript out of range For information on how your program can cause an assertion failure, see the Visual $\mathrm{C}++$ documentation on asserts. (Press Retry to debug the application) というエラーメッセージが出てきますがこれはどういう意味でしょうか?
tiitoi

2020/09/05 13:03

Error:invalid stod augument なので、数値としてパースできないものが CSV ファイルに含まれているのではないでしょうか。 CSV ファイルにヘッダーが入っていたりしませんか?CSV ファイルをどっかにアップロードするか、値の例とかを貼っていただけないと具体例なことはわかりません。
tiitoi

2020/09/05 21:26

両方ともアクセス権がないと言われてファイルが閲覧できないです 共有リンクを取得して貼り付けてください https://hep.eiz.jp/google-drive-share/#_8211 > これはどのような原因が考えられますか? CSV ファイルに数値として変換できない値がある、CSV のフォーマットが間違っているなどファイルに原因があります。
Kinsho

2020/09/06 01:26

調べていたところ普通のコンマ区切りのcsvとUTF-8(BOM付き)csvが混在していたようです.ご迷惑をおかけしました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問