C++プログラミングにおいて、ファイル操作は基本的かつ重要なスキルです。本記事では、ifstreamとofstreamを使用したファイルの読み書き方法について、基本から応用までを丁寧に解説します。具体的なコード例やエラーハンドリングの方法も紹介し、実践的なファイル操作のスキルを身につけましょう。
相対パスは実行時の作業ディレクトリーを基準に解決されます。std::ofstreamの通常の開き方は既存ファイルを切り詰めるため、試験用ファイルで確認してください。追記はstd::ios::appを明示します。
ifstreamとofstreamの基本概要
C++でファイルの読み込みと書き込みを行う際に使用されるのが、ifstreamとofstreamです。ifstreamは入力ファイルストリームで、ファイルからデータを読み込むために使用されます。ofstreamは出力ファイルストリームで、ファイルにデータを書き込むために使用されます。これらのストリームは、ヘッダーファイルをインクルードすることで利用可能になります。
ifstreamの基本構文
ifstreamの基本的な使用方法は以下の通りです:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ifstream inputFile("example.txt");
if (inputFile.is_open()) {
// ファイルから読み込み処理
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}ofstreamの基本構文
ofstreamの基本的な使用方法は以下の通りです:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ofstream outputFile("example.txt");
if (outputFile.is_open()) {
// ファイルへ書き込み処理
outputFile.close();
if (!outputFile) {
std::cerr << "書込みまたはクローズに失敗しました。" << std::endl;
return 1;
}
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}ファイルを開く方法
ifstreamとofstreamを使用してファイルを開く方法について説明します。ファイルを開く際には、ファイル名とモードを指定します。
ifstreamでファイルを開く
ifstreamは入力ファイルストリームとして使用され、ファイルからデータを読み込むために用いられます。以下は基本的な構文です:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ifstream inputFile("input.txt");
if (!inputFile) {
std::cerr << "ファイルを開けませんでした。" << std::endl;
return 1;
}
// ファイルの読み込み処理
inputFile.close();
return 0;
}この例では、”input.txt”というファイルを開こうとしています。ファイルが存在しない場合、エラーメッセージを表示します。
ofstreamでファイルを開く
ofstreamは出力ファイルストリームとして使用され、ファイルにデータを書き込むために用いられます。以下は基本的な構文です:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ofstream outputFile("output.txt");
if (!outputFile) {
std::cerr << "ファイルを開けませんでした。" << std::endl;
return 1;
}
// ファイルへの書き込み処理
outputFile.close();
return 0;
}この例では、”output.txt”というファイルを開いて書き込みを行います。ファイルが開けない場合、エラーメッセージを表示します。
ファイルオープンモードの指定
ファイルを開く際に、追加のモードを指定することができます。例えば、既存のファイルに追加書き込みを行う場合は、std::ios::appモードを使用します:
std::ofstream outputFile("output.txt", std::ios::app);このモードでは、既存のファイルの末尾にデータが追加されます。
ファイルへのデータ書き込み
ofstreamを使ってファイルにデータを書き込む方法について説明します。具体的なコード例を通じて、基本的な書き込み操作を理解しましょう。
基本的な書き込み操作
ofstreamを使用してファイルにデータを書き込む基本的な手順は以下の通りです:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ofstream outputFile("output.txt");
if (outputFile.is_open()) {
outputFile << "Hello, World!" << std::endl;
outputFile << "This is a test." << std::endl;
outputFile.close();
if (!outputFile) {
std::cerr << "書込みまたはクローズに失敗しました。" << std::endl;
return 1;
}
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、”output.txt”というファイルを開いて、2行のテキストを書き込んでいます。outputFile.close()を使用して、書き込みが完了した後にファイルを閉じています。
複数行のデータ書き込み
複数行のデータを書き込む場合、ループを使用すると便利です:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ofstream outputFile("output.txt");
if (outputFile.is_open()) {
for (int i = 1; i <= 5; ++i) {
outputFile << "Line " << i << std::endl;
}
outputFile.close();
if (!outputFile) {
std::cerr << "書込みまたはクローズに失敗しました。" << std::endl;
return 1;
}
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、1行目から5行目までのテキストをファイルに書き込んでいます。
数値データの書き込み
テキストだけでなく、数値データも書き込むことができます:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ofstream outputFile("output.txt");
if (outputFile.is_open()) {
int number = 42;
double pi = 3.14159;
outputFile << "Number: " << number << std::endl;
outputFile << "Pi: " << pi << std::endl;
outputFile.close();
if (!outputFile) {
std::cerr << "書込みまたはクローズに失敗しました。" << std::endl;
return 1;
}
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、整数と浮動小数点数をファイルに書き込んでいます。
ファイルからのデータ読み込み
ifstreamを使ってファイルからデータを読み込む方法について説明します。具体的なコード例を通じて、基本的な読み込み操作を理解しましょう。
基本的な読み込み操作
ifstreamを使用してファイルからデータを読み込む基本的な手順は以下の通りです:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
#include <string>
int main() {
std::ifstream inputFile("input.txt");
if (inputFile.is_open()) {
std::string line;
while (std::getline(inputFile, line)) {
std::cout << line << std::endl;
}
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、”input.txt”というファイルを開いて、各行を読み込みながらコンソールに出力しています。
単語単位の読み込み
ファイルから単語単位でデータを読み込む場合は、>>演算子を使用します:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ifstream inputFile("input.txt");
if (inputFile.is_open()) {
std::string word;
while (inputFile >> word) {
std::cout << word << std::endl;
}
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、ファイルから単語ごとに読み込み、各単語をコンソールに出力しています。
数値データの読み込み
テキストだけでなく、数値データも読み込むことができます:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ifstream inputFile("numbers.txt");
if (inputFile.is_open()) {
int number;
while (inputFile >> number) {
std::cout << "Number: " << number << std::endl;
}
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例は正しい整数が並ぶ入力用です。数値変換ではEOFと範囲外エラーが同時に発生する場合もあるため、厳密な入力検証には文字列として読み、変換結果と範囲を別に検査します。
ファイルの終端に達したときの処理
eof()は直前の入力結果を表します。読み取る前のwhile (!eof())ではなく、getlineの成功をループ条件にし、終了後に状態を確認します:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ifstream inputFile("input.txt");
if (inputFile.is_open()) {
std::string line;
while (std::getline(inputFile, line)) {
std::cout << line << std::endl;
}
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、ファイルの終端に達するまで各行を読み込み、コンソールに出力しています。
ファイルのクローズ方法
ifstream/ofstreamはRAIIにより、スコープを抜けて破棄されるとファイルを閉じます。明示的close()を書かないこと自体がメモリリークではありません。ただし書込み・close時の失敗を検出したい場合は、明示的に閉じて状態を確認します。
ファイルをクローズする理由
ファイルをクローズする理由は以下の通りです:
- ファイルハンドルの解放:開かれたファイルはオペレーティングシステムによってリソースとして管理されます。明示的close()またはストリーム破棄時に解放されます。
- データの整合性の確保:ファイルに書き込みを行った場合、close時にも書込みが失敗することがあるため、状態を確認します。close成功と電源断後の永続性保証は別です。
- RAIIによる管理:ストリームの寿命を必要な範囲に限定し、不要なファイルを長時間開いたままにしないようにします。
ifstreamをクローズする方法
ifstreamでファイルを読み込んだ後、close()メソッドを使用してファイルをクローズします:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ifstream inputFile("input.txt");
if (inputFile.is_open()) {
std::string line;
while (std::getline(inputFile, line)) {
std::cout << line << std::endl;
}
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close(); // ファイルをクローズ
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、ファイルの読み込みが完了した後、inputFile.close()を呼び出してファイルをクローズしています。
ofstreamをクローズする方法
ofstreamでファイルに書き込んだ後も、同様にclose()メソッドを使用してファイルをクローズします:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ofstream outputFile("output.txt");
if (outputFile.is_open()) {
outputFile << "Hello, World!" << std::endl;
outputFile.close();
if (!outputFile) {
std::cerr << "書込みまたはクローズに失敗しました。" << std::endl;
return 1;
} // ファイルをクローズ
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、ファイルへの書き込みが完了した後、outputFile.close()を呼び出してファイルをクローズしています。
エラーハンドリング
ファイル操作中に発生する可能性のあるエラーを適切に処理することは、信頼性の高いプログラムを作成するために重要です。ここでは、ファイル操作中のエラーハンドリング方法について具体的に説明します。
ファイルが開けない場合のエラー処理
ファイルを開く際にエラーが発生した場合は、以下のようにエラーメッセージを表示することで対応できます:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ifstream inputFile("nonexistent.txt");
if (!inputFile) {
std::cerr << "ファイルを開けませんでした。" << std::endl;
return 1;
}
inputFile.close();
return 0;
}この例では、存在しないファイルを開こうとした場合にエラーメッセージを表示します。
読み込みエラーの処理
ファイルからデータを読み込む際にエラーが発生した場合は、fail()メソッドを使用してエラーを検出できます:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
#include <string>
int main() {
std::ifstream inputFile("input.txt");
if (inputFile.is_open()) {
std::string line;
while (std::getline(inputFile, line)) {
std::cout << line << std::endl;
}
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、読み込み中にエラーが発生した場合にエラーメッセージを表示します。
書き込みエラーの処理
ファイルにデータを書き込む際にエラーが発生した場合も、fail()メソッドを使用してエラーを検出できます:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ofstream outputFile("output.txt");
if (outputFile.is_open()) {
outputFile << "Hello, World!" << std::endl;
if (outputFile.fail()) {
std::cerr << "書き込みエラーが発生しました。" << std::endl;
}
outputFile.close();
if (!outputFile) {
std::cerr << "書込みまたはクローズに失敗しました。" << std::endl;
return 1;
}
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、書き込み中にエラーが発生した場合にエラーメッセージを表示します。
例外を使ったエラーハンドリング
例外を使用することで、より高度なエラーハンドリングを行うことができます。以下は例外を使ったエラーハンドリングの例です:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
#include <exception>
int main() {
try {
std::ifstream inputFile("input.txt");
if (!inputFile) {
throw std::runtime_error("ファイルを開けませんでした。");
}
std::string line;
while (std::getline(inputFile, line)) {
std::cout << line << std::endl;
}
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return 1;
}
return 0;
}この例では開けない場合に例外を投げ、読取り終了後にもストリーム状態を確認します。ストリームは通常、失敗時に自動で例外を投げる設定ではありません。
バイナリファイルの読み書き
バイナリファイルに対するifstreamとofstreamの使用方法について説明します。テキストファイルと異なり、バイナリファイルではデータをそのままの形式で読み書きするため、特別な処理が必要です。
バイナリファイルの書き込み
バイナリファイルにデータを書き込む場合、ofstreamをバイナリモードで開く必要があります。以下はその例です:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ofstream outputFile("output.bin", std::ios::binary);
if (outputFile.is_open()) {
int number = 12345;
outputFile.write(reinterpret_cast<char*>(&number), sizeof(number));
outputFile.close();
if (!outputFile) {
std::cerr << "書込みまたはクローズに失敗しました。" << std::endl;
return 1;
}
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例は同じ整数表現・サイズ・バイト順の環境で読み戻す学習用です。intのメモリー表現をそのまま書く方式は、異なる環境で交換する汎用ファイル形式ではありません。
バイナリファイルの読み込み
バイナリファイルからデータを読み込む場合、ifstreamをバイナリモードで開きます。以下はその例です:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ifstream inputFile("output.bin", std::ios::binary);
if (inputFile.is_open()) {
int number{};
if (!inputFile.read(reinterpret_cast<char*>(&number), sizeof(number))) {
std::cerr << "データ不足または読取り失敗" << std::endl;
return 1;
}
std::cout << "読み込んだ数値: " << number << std::endl;
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、”output.bin”から整数値をバイナリ形式で読み込み、コンソールに出力しています。
バイナリデータの配列の読み書き
配列形式のバイナリデータを扱うこともできます。以下にその例を示します:
バイナリデータの書き込み:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ofstream outputFile("output_array.bin", std::ios::binary);
if (outputFile.is_open()) {
int numbers[] = {1, 2, 3, 4, 5};
outputFile.write(reinterpret_cast<char*>(numbers), sizeof(numbers));
outputFile.close();
if (!outputFile) {
std::cerr << "書込みまたはクローズに失敗しました。" << std::endl;
return 1;
}
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}バイナリデータの読み込み:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
int main() {
std::ifstream inputFile("output_array.bin", std::ios::binary);
if (inputFile.is_open()) {
int numbers[5]{};
if (!inputFile.read(reinterpret_cast<char*>(numbers), sizeof(numbers))) {
std::cerr << "データ不足または読取り失敗" << std::endl;
return 1;
}
for (int number : numbers) {
std::cout << "読み込んだ数値: " << number << std::endl;
}
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、整数の配列をバイナリ形式でファイルに書き込み、その後読み込んでコンソールに出力しています。
応用例:CSVファイルの読み書き
以下は、値にカンマ・引用符・改行がなく、列数と数値が正しいサンプル限定の練習です。単純なgetlineのカンマ分割は、引用符付きCSVの汎用パーサーではありません。実データではCSV対応ライブラリーと、列数・空欄・stoi/stodの例外や末尾文字・文字コードの検証が必要です。
CSVファイルの書き込み
まず、ofstreamを使用してCSVファイルにデータを書き込む方法を説明します:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
#include <vector>
#include <string>
int main() {
std::ofstream outputFile("data.csv");
if (outputFile.is_open()) {
// ヘッダー行を書き込む
outputFile << "Name,Age,Occupation" << std::endl;
// データ行を書き込む
outputFile << "Alice,30,Engineer" << std::endl;
outputFile << "Bob,25,Designer" << std::endl;
outputFile << "Charlie,35,Teacher" << std::endl;
outputFile.close();
if (!outputFile) {
std::cerr << "書込みまたはクローズに失敗しました。" << std::endl;
return 1;
}
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、”data.csv”というファイルに3人分のデータを書き込んでいます。ヘッダー行も含めて書き込んでいます。
CSVファイルの読み込み
次に、ifstreamを使用してCSVファイルからデータを読み込む方法を説明します:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
#include <sstream>
#include <vector>
#include <string>
struct Person {
std::string name;
int age;
std::string occupation;
};
int main() {
std::ifstream inputFile("data.csv");
if (inputFile.is_open()) {
std::string line;
std::vector<Person> people;
// ヘッダー行をスキップ
std::getline(inputFile, line);
// データ行を読み込む
while (std::getline(inputFile, line)) {
std::stringstream ss(line);
std::string name, ageStr, occupation;
std::getline(ss, name, ',');
std::getline(ss, ageStr, ',');
std::getline(ss, occupation, ',');
Person person;
person.name = name;
person.age = std::stoi(ageStr);
person.occupation = occupation;
people.push_back(person);
}
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
// 読み込んだデータを出力する
for (const Person& person : people) {
std::cout << "Name: " << person.name
<< ", Age: " << person.age
<< ", Occupation: " << person.occupation
<< std::endl;
}
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、”data.csv”からデータを読み込み、Person構造体に格納して、コンソールに出力しています。ヘッダー行をスキップし、各行のデータをカンマで区切って読み込んでいます。
CSVファイルの読み書きの応用
CSVファイルの読み書きは、データのインポートやエクスポート、データベースとの連携など、さまざまな応用が可能です。以下は、CSVファイルを読み込み、特定の条件に基づいてフィルタリングする例です:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
#include <sstream>
#include <vector>
#include <string>
struct Person {
std::string name;
int age;
std::string occupation;
};
int main() {
std::ifstream inputFile("data.csv");
std::ofstream outputFile("filtered_data.csv");
if (inputFile.is_open() && outputFile.is_open()) {
std::string line;
std::vector<Person> people;
// ヘッダー行を読み込み、書き出す
std::getline(inputFile, line);
outputFile << line << std::endl;
// データ行を読み込む
while (std::getline(inputFile, line)) {
std::stringstream ss(line);
std::string name, ageStr, occupation;
std::getline(ss, name, ',');
std::getline(ss, ageStr, ',');
std::getline(ss, occupation, ',');
Person person;
person.name = name;
person.age = std::stoi(ageStr);
person.occupation = occupation;
// 年齢が30以上の人をフィルタリングして書き出す
if (person.age >= 30) {
outputFile << person.name << "," << person.age << "," << person.occupation << std::endl;
}
}
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
outputFile.close();
if (!outputFile) {
std::cerr << "書込みまたはクローズに失敗しました。" << std::endl;
return 1;
}
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
}
return 0;
}この例では、”data.csv”からデータを読み込み、年齢が30以上の人のデータを”filtered_data.csv”に書き出しています。
演習問題:ファイル操作プログラムの作成
ここでは、これまで学んだifstreamとofstreamの知識を活用して、実際にファイル操作プログラムを作成するための演習問題を提供します。以下の課題に取り組んで、ファイル操作のスキルをさらに磨きましょう。
演習1:学生情報の読み書き
以下の仕様に従って、学生の情報を管理するプログラムを作成してください。
students.csvファイルに学生の情報(名前、年齢、成績)を書き込みます。students.csvファイルから学生の情報を読み込み、コンソールに出力します。- 学生の情報を構造体で管理します。
ヒント:
- 学生の情報を格納する構造体を定義します。
- 学生の情報を入力し、CSVファイルに書き込みます。
- CSVファイルからデータを読み込み、構造体に格納します。
コード例:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
#include <vector>
#include <sstream>
struct Student {
std::string name;
int age;
double grade;
};
int main() {
std::vector<Student> students = {
{"Alice", 20, 85.5},
{"Bob", 22, 90.0},
{"Charlie", 19, 78.2}
};
// 学生情報をファイルに書き込む
std::ofstream outputFile("students.csv");
if (outputFile.is_open()) {
outputFile << "Name,Age,Grade" << std::endl;
for (const Student& student : students) {
outputFile << student.name << "," << student.age << "," << student.grade << std::endl;
}
outputFile.close();
if (!outputFile) {
std::cerr << "書込みまたはクローズに失敗しました。" << std::endl;
return 1;
}
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
return 1;
}
// 学生情報をファイルから読み込む
std::ifstream inputFile("students.csv");
if (inputFile.is_open()) {
std::string line;
std::getline(inputFile, line); // ヘッダー行をスキップ
while (std::getline(inputFile, line)) {
std::stringstream ss(line);
std::string name, ageStr, gradeStr;
std::getline(ss, name, ',');
std::getline(ss, ageStr, ',');
std::getline(ss, gradeStr, ',');
Student student;
student.name = name;
student.age = std::stoi(ageStr);
student.grade = std::stod(gradeStr);
std::cout << "Name: " << student.name
<< ", Age: " << student.age
<< ", Grade: " << student.grade << std::endl;
}
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
return 1;
}
return 0;
}演習2:ログファイルの分析
以下の仕様に従って、ログファイルを分析するプログラムを作成してください。
logs.txtファイルからログデータを読み込みます。- ログのエントリを解析し、エラー(”ERROR”を含む行)をカウントします。
- エラー数をコンソールに出力します。
ヒント:
- ログファイルの各行を読み込み、”ERROR”という文字列を含むかチェックします。
- エラー行のカウントを行います。
コード例:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
#include <string>
int main() {
std::ifstream inputFile("logs.txt");
int errorCount = 0;
if (inputFile.is_open()) {
std::string line;
while (std::getline(inputFile, line)) {
if (line.find("ERROR") != std::string::npos) {
++errorCount;
}
}
if (inputFile.bad() || (inputFile.fail() && !inputFile.eof())) {
std::cerr << "読み込みに失敗しました。" << std::endl;
return 1;
}
inputFile.close();
} else {
std::cerr << "ファイルを開けませんでした。" << std::endl;
return 1;
}
std::cout << "Total ERROR entries: " << errorCount << std::endl;
return 0;
}まとめ
本記事では、C++におけるifstreamとofstreamを使用したファイルの読み書き方法について詳しく解説しました。基本的なファイルのオープン、データの読み書き、エラーハンドリングからバイナリファイルやCSVファイルの操作まで、多岐にわたる内容をカバーしました。実際のプログラム例や演習問題を通じて、実践的なスキルを身につけることができたでしょう。これらの知識を応用し、より高度なファイル操作プログラムを作成してみてください。


コメント