[C++] CSVを数値として読み込んで処理する方法
C++でCSVを数値として読み込むには、標準ライブラリの<fstream>
を使用してファイルを開き、std::getline
で1行ずつ読み込みます。
各行をカンマ区切りで分割するにはstd::stringstream
を利用します。
分割後、std::stoi
やstd::stod
を使って文字列を数値に変換します。
数値データはstd::vector
や2次元配列に格納すると便利です。
数値データへの変換
CSVファイルから読み込んだデータは、通常は文字列として扱われます。
そのため、数値として処理するためには、文字列を適切な数値型に変換する必要があります。
C++では、std::stoi
やstd::stof
などの関数を使用して、文字列を整数や浮動小数点数に変換できます。
以下に、CSVから読み込んだデータを数値に変換するサンプルコードを示します。
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
int main() {
std::ifstream file("data.csv"); // CSVファイルを開く
std::string line;
std::vector<int> numbers; // 整数を格納するベクター
// ファイルが開けたか確認
if (file.is_open()) {
while (std::getline(file, line)) { // 行ごとに読み込む
std::stringstream ss(line); // 行をストリームに変換
std::string value;
// カンマで区切られた値を読み込む
while (std::getline(ss, value, ',')) {
// 文字列を整数に変換
int number = std::stoi(value); // 文字列を整数に変換
numbers.push_back(number); // ベクターに追加
}
}
file.close(); // ファイルを閉じる
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
// 読み込んだ数値を表示
for (const int& num : numbers) {
std::cout << num << std::endl; // 数値を出力
}
return 0;
}
10
20
30
40
50
このコードでは、data.csv
というファイルから数値を読み込み、カンマで区切られた各値を整数に変換してベクターに格納しています。
最終的に、読み込んだ数値をコンソールに出力します。
std::stoi
を使用することで、文字列を簡単に整数に変換できることがわかります。
読み込んだデータの格納方法
CSVファイルから読み込んだデータを格納する方法はいくつかありますが、C++では主に配列やベクターを使用することが一般的です。
特に、std::vector
は動的にサイズを変更できるため、CSVデータのように行数が不定な場合に便利です。
以下に、CSVデータをベクターに格納する方法を示すサンプルコードを紹介します。
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
int main() {
std::ifstream file("data.csv"); // CSVファイルを開く
std::string line;
std::vector<std::vector<int>> data; // 整数の2次元ベクター
// ファイルが開けたか確認
if (file.is_open()) {
while (std::getline(file, line)) { // 行ごとに読み込む
std::stringstream ss(line); // 行をストリームに変換
std::string value;
std::vector<int> row; // 行ごとの整数を格納するベクター
// カンマで区切られた値を読み込む
while (std::getline(ss, value, ',')) {
// 文字列を整数に変換
int number = std::stoi(value); // 文字列を整数に変換
row.push_back(number); // 行のベクターに追加
}
data.push_back(row); // 行のベクターを全体のデータに追加
}
file.close(); // ファイルを閉じる
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
// 読み込んだデータを表示
for (const auto& row : data) {
for (const int& num : row) {
std::cout << num << " "; // 行の数値を出力
}
std::cout << std::endl; // 行の終わりで改行
}
return 0;
}
10 20 30
40 50 60
70 80 90
このコードでは、CSVファイルから読み込んだデータを2次元ベクターに格納しています。
各行はstd::vector<int>
として格納され、全体のデータはstd::vector<std::vector<int>>
に追加されます。
これにより、行数や列数が不定のデータを柔軟に扱うことができます。
最終的に、読み込んだデータを行ごとに出力しています。
CSVデータの処理例
CSVデータを読み込んだ後、さまざまな処理を行うことができます。
例えば、数値の合計や平均を計算したり、特定の条件に基づいてフィルタリングしたりすることが可能です。
以下に、CSVデータから読み込んだ数値の合計と平均を計算するサンプルコードを示します。
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <numeric> // std::accumulateを使用するために必要
int main() {
std::ifstream file("data.csv"); // CSVファイルを開く
std::string line;
std::vector<int> numbers; // 整数を格納するベクター
// ファイルが開けたか確認
if (file.is_open()) {
while (std::getline(file, line)) { // 行ごとに読み込む
std::stringstream ss(line); // 行をストリームに変換
std::string value;
// カンマで区切られた値を読み込む
while (std::getline(ss, value, ',')) {
// 文字列を整数に変換
int number = std::stoi(value); // 文字列を整数に変換
numbers.push_back(number); // ベクターに追加
}
}
file.close(); // ファイルを閉じる
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
// 数値の合計を計算
int sum = std::accumulate(numbers.begin(), numbers.end(), 0); // 合計を計算
// 数値の平均を計算
double average = static_cast<double>(sum) / numbers.size(); // 平均を計算
// 結果を表示
std::cout << "合計: " << sum << std::endl; // 合計を出力
std::cout << "平均: " << average << std::endl; // 平均を出力
return 0;
}
合計: 300
平均: 30
このコードでは、CSVファイルから読み込んだ数値の合計と平均を計算しています。
std::accumulate
を使用して合計を計算し、合計を要素数で割ることで平均を求めています。
これにより、データの基本的な統計情報を簡単に取得することができます。
CSVデータの処理は、データ分析やレポート作成において非常に重要なステップです。
応用的なCSV処理
CSVデータの処理は基本的な操作だけでなく、より複雑な処理も可能です。
例えば、特定の条件に基づいてデータをフィルタリングしたり、データをソートしたり、さらには新しいCSVファイルに書き出すこともできます。
以下に、特定の条件でフィルタリングし、結果を新しいCSVファイルに書き出すサンプルコードを示します。
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm> // std::sortを使用するために必要
int main() {
std::ifstream inputFile("data.csv"); // 入力用CSVファイルを開く
std::ofstream outputFile("filtered_data.csv"); // 出力用CSVファイルを開く
std::string line;
std::vector<int> numbers; // 整数を格納するベクター
// 入力ファイルが開けたか確認
if (inputFile.is_open()) {
while (std::getline(inputFile, line)) { // 行ごとに読み込む
std::stringstream ss(line); // 行をストリームに変換
std::string value;
// カンマで区切られた値を読み込む
while (std::getline(ss, value, ',')) {
// 文字列を整数に変換
int number = std::stoi(value); // 文字列を整数に変換
numbers.push_back(number); // ベクターに追加
}
}
inputFile.close(); // 入力ファイルを閉じる
} else {
std::cerr << "入力ファイルを開けませんでした。" << std::endl;
return 1; // エラーコードを返す
}
// 50以上の数値をフィルタリング
std::vector<int> filteredNumbers;
std::copy_if(numbers.begin(), numbers.end(), std::back_inserter(filteredNumbers),
[](int num) { return num >= 50; }); // 条件に基づいてフィルタリング
// フィルタリングしたデータを新しいCSVファイルに書き出す
if (outputFile.is_open()) {
for (const int& num : filteredNumbers) {
outputFile << num << std::endl; // 数値を出力
}
outputFile.close(); // 出力ファイルを閉じる
} else {
std::cerr << "出力ファイルを開けませんでした。" << std::endl;
return 1; // エラーコードを返す
}
std::cout << "フィルタリングしたデータを 'filtered_data.csv' に書き出しました。" << std::endl;
return 0;
}
フィルタリングしたデータを 'filtered_data.csv' に書き出しました。
このコードでは、CSVファイルから読み込んだ数値の中から50以上の数値をフィルタリングし、新しいCSVファイルfiltered_data.csv
に書き出しています。
std::copy_if
を使用して条件に合った数値を抽出し、出力ファイルに書き込むことで、データの選別が簡単に行えます。
このような応用的な処理は、データ分析やレポート作成において非常に役立ちます。
まとめ
この記事では、C++を使用してCSVファイルから数値データを読み込み、処理する方法について詳しく解説しました。
具体的には、数値データへの変換、データの格納方法、基本的な処理例、さらには応用的なCSV処理について触れました。
これらの知識を活用して、実際のデータ分析やプログラムの開発に役立ててみてください。
データ処理のスキルを向上させるために、ぜひ自分自身でさまざまなCSVファイルを扱ってみることをお勧めします。