
ゆうき( @BASEBALLY15 )です^^
今回はどうしたんじゃ?
C++を使って,テキストファイル内のデータを読み込んだり,テキストファイルを作成して書き込む方法を教えてほしいです!
了解じゃ!

目次
具体的に何が出来るの?
この記事を最後まで読むと,
以下の画像の様に,C++によるテキストファイルの読み込みと書き込みの方法を理解することが出来ます.

また,今回は,4列13,129行の数字が書かれたテキストファイル(input.txt)から,4列目の値が『100以上』の行のみを別のテキストファイル(output.txt)に書き出す処理を行います.

開発環境を載せておくよ!
まず,始めに,テキストファイルの読み込みと書き込みを行う際の環境を紹介します.
(※今回紹介する方法は,エディタやライブラリのバージョンが,以下のものと異なる場合でも使うことが出来ます.)
エディタ :Visual Studio 2015
言語 :C++
ライブラリ:OpenCV 3.4.10
OpenCVを使えるように設定しよう!
今回紹介する方法では,OpenCVを使うため,OpenCVを使えるように設定していない方は,先に以下の記事を読むことをオススメします^^
C++を使って,テキストファイルの読み込みと書き込みを行う方法とは?
それでは,早速,以下の流れで,テキストファイルの読み込みと書き込みを行う方法をご紹介します.
2. 各コードの詳細 について
全体のコード
#include <iostream>
#include <string> //std::cinを使用
#include <fstream> //std::ifstreamを使用
#include <opencv2/opencv.hpp> //std::vectorを使用
struct input_data
{
double a;
double b;
double c;
double d;
};
int main()
{
struct input_data input;
std::vector<struct input_data> all_input;
//input_data
std::cout << "Input Data = " << std::endl;
std::string input_text_path;
std::cin >> input_text_path;
//読み込む用のファイルを用意
std::ifstream input_text_data;
input_text_data.open(input_text_path);
//output_data
std::cout << "Output Data = " << std::endl;
std::string output_text_path;
std::cin >> output_text_path;
//書き込む用のファイルを用意
std::ofstream output_text_data;
output_text_data.open(output_text_path);
while (1)
{
if (!input_text_data.eof())
{
input_text_data >> input.a;
input_text_data >> input.b;
input_text_data >> input.c;
input_text_data >> input.d;
all_input.push_back(input);
}
else
{
break;
}
}
for (int i = 0; i < all_input.size(); i++)
{
if (all_input[i].d >= 100.0)
{
output_text_data << all_input[i].a << "\t" << all_input[i].b << "\t" << all_input[i].c << "\t" << all_input[i].d << "\n";
std::cout << "\t" << all_input[i].a << "\t" << all_input[i].b << "\t" << all_input[i].c << "\t" << all_input[i].d << "\n";
}
}
input_text_data.close();
output_text_data.close();
//clear
all_input.clear();
all_input.shrink_to_fit();
std::cout << "OK!" << std::endl;
return 0;
}
各コードの詳細
構造体を作成する
struct input_data
{
double a;
double b;
double c;
double d;
};
テキストファイルの各列の値を編集するために,構造体を作成します.
構造体を使うことで,int型やdouble型,char型など,複数の型を指定することが出来きます.
ちなみに,今回は,テキストファイル内の数字が小数点以下を含むため,double型を指定しています.
配列(vector)を用意する
struct input_data input;
std::vector<struct input_data> all_input;
まず,
struct input_data input;
と書くことで,上で作成した『構造体(struct)』をメイン関数内で使えるようにします.
そして,
std::vector<struct input_data> all_input;
と書くことで,下の図の様に,1行ずつ,値を配列に格納するための準備を行います.

読み込む用と書き込む用のファイルを作成する
//input_data
std::cout << "Input Data = " << std::endl;
std::string input_text_path;
std::cin >> input_text_path;
//読み込む用のファイルを用意
std::ifstream input_text_data;
input_text_data.open(input_text_path);
//output_data
std::cout << "Output Data = " << std::endl;
std::string output_text_path;
std::cin >> output_text_path;
//書き込む用のファイルを用意
std::ofstream output_text_data;
output_text_data.open(output_text_path);
まず,
std::cout << "Input Data = " << std::endl;
std::string input_text_path;
std::cin >> input_text_path;
と書くことで,コマンドプロンプト上からテキストファイルを読み込むことが出来ます.
そして,
std::ifstream input_text_data;
input_text_data.open(input_text_path);
と書くことで,コマンドプロンプト上から読み込んだテキストファイルを,読み込み用として開くことが出来ます.
また,同じ流れで,書き込み用のファイルも作成します.
ちなみに,
std::ofstream
と書くことで,書き込み用のファイルを作成することが出来ます.
テキストファイル内のデータを読み込む
while (1)
{
if (!input_text_data.eof())
{
input_text_data >> input.a;
input_text_data >> input.b;
input_text_data >> input.c;
input_text_data >> input.d;
all_input.push_back(input);
}
else
{
break;
}
}
処理を繰り返し行うために,
while (1)
と書きます.
そして,while文の中に,テキストファイル内のデータを読み込むためのコードを書きます.
if (!input_text_data.eof())
{
input_text_data >> input.a;
input_text_data >> input.b;
input_text_data >> input.c;
input_text_data >> input.d;
all_input.push_back(input);
}
と書くことで,テキストファイル内のデータを最後までスキャンすることが出来ます.
ちなみに,
all_input.push_back(input);
は,1行ごとに読み込んだ値を,メイン関数の始めで定義した『all_input』という配列に格納しています.
また,
else
{
break;
}
と書くことで,テキストファイル内のデータを全てスキャンし終わったら,while文から抜けるという処理を行うことが出来ます.
テキストファイルに書き込む
for (int i = 0; i < all_input.size(); i++)
{
if (all_input[i].d >= 100.0)
{
output_text_data << all_input[i].a << "\t" << all_input[i].b << "\t" << all_input[i].c << "\t" << all_input[i].d << "\n";
}
}
まず,
for (int i = 0; i < all_input.size(); i++)
と書くことで,先ほど格納したデータの数だけ処理を繰り返し行うことが出来ます.
そして,
if (all_input[i].d >= 100.0)
{
output_text_data << all_input[i].a << "\t" << all_input[i].b << "\t" << all_input[i].c << "\t" << all_input[i].d << "\n";
}
と書くことで,4列目の値が100以上の行のみを別のテキストファイルに書き出す処理を行うことが出来ます.
ちなみに,『\t』は半角スペース空けるという意味で,『\n』は改行を意味しています.
ファイルを閉じる&配列をクリアにする
input_text_data.close();
output_text_data.close();
//clear
all_input.clear();
all_input.shrink_to_fit();
return 0;
最後に,
input_text_data.close();
output_text_data.close();
と書くことで,読み込み用と書き込み用のファイルを閉じます.
そして,
all_input.clear();
all_input.shrink_to_fit();
と書くことで,配列(vector)内を最初の状態に戻しておきます.

正直,この処理は,今回のコードでは,必要ありません.
今回は,1つのテキストファイルを使ったのですが,もし複数のテキストファイルを読み込む際に『clear』と『shrink_to_fit』を使う機会が増えます.
終わりに
この記事では,C++を使って,テキストファイルの読み込みと書き込みを行う方法をご紹介しました.
プログラミングの勉強をしていると,何かとテキストファイルを扱う機会が多いです.
是非,この記事を読んで,テキストファイルの扱い方を勉強してください^^
この記事があなたの役に立てたら幸いです^^
それでは,Goodbye!