エラー処理と状態
ストリームの状態を確認します
「エラー処理と状態」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。
ストリームの状態ビット
すべてのストリームは、状態フラグによって自身の状態を追跡します。
- goodbit:すべて正常です。
- eofbit:ファイル末尾に到達しました。
- failbit:論理エラー(形式が不正)です。
- badbit:重大なI/Oエラーです。
#include <iostream>
#include <fstream>
int main() {
std::ifstream in("missing_98765.txt");
std::cout << std::boolalpha << "good: " << in.good() << '\n';
return 0;
}ストリームをテストする
ストリームはboolに変換できます。使用可能な場合はtrueになります。if (!in)と書くと、失敗を簡潔に検出できます。
#include <iostream>
#include <fstream>
int main() {
std::ifstream in("nope_55555.txt");
if (!in) std::cout << "stream not usable\n";
else std::cout << "ok\n";
return 0;
}good、eof、fail、bad
各フラグには、good()、eof()、fail()、bad()という確認用メソッドがあります。
#include <iostream>
#include <sstream>
int main() {
std::istringstream s("abc");
int x;
s >> x; // fails: not a number
std::cout << std::boolalpha;
std::cout << "fail: " << s.fail() << '\n';
std::cout << "bad: " << s.bad() << '\n';
return 0;
}抽出の失敗
>>で期待した型を解析できない場合、failbitが設定され、対象の値は変更されません。
#include <iostream>
#include <sstream>
int main() {
std::istringstream s("hello");
int n = -1;
if (!(s >> n)) std::cout << "could not read an int, n stays " << n << '\n';
return 0;
}状態をクリアする
失敗フラグが設定されると、clear()を呼び出してリセットするまで、ストリームは使用できない状態のままです。
#include <iostream>
#include <sstream>
int main() {
std::istringstream s("x 42");
int n;
s >> n; // fails on 'x'
s.clear(); // reset state
std::string word;
s >> word; // now reads 'x'
std::cout << "recovered: " << word << '\n';
return 0;
}不正な入力を無視する
clear()の後、再試行する前にignore()を使って問題のある文字を破棄します。
#include <iostream>
#include <sstream>
#include <limits>
int main() {
std::istringstream s("bad 100");
int n;
while (!(s >> n)) {
s.clear();
s.ignore(std::numeric_limits<std::streamsize>::max(), ' ');
}
std::cout << "read " << n << '\n';
return 0;
}EOFとエラーを区別する
読み取りループが終了した後、正常なeof()による終了なのか、実際のbad()エラーなのかを確認します。
#include <iostream>
#include <sstream>
int main() {
std::istringstream s("1 2 3");
int x;
while (s >> x) {}
std::cout << std::boolalpha << "reached eof: " << s.eof() << '\n';
std::cout << "hardware error: " << s.bad() << '\n';
return 0;
}オープン直後に確認する
ファイルを開いた直後には必ずストリームを確認し、存在しないパスや読み取れないパスを早期に検出してください。
#include <iostream>
#include <fstream>
int main() {
std::ifstream in("absent_11111.txt");
if (!in.is_open()) {
std::cout << "open failed, aborting\n";
return 1;
}
std::cout << "never reached\n";
return 0;
}例外を有効にする
exceptions()を使うと、エラー発生時にストリームが例外をスローするように設定できます。これにより、暗黙に失敗する処理を捕捉可能なstd::ios_base::failureに変えられます。
#include <iostream>
#include <fstream>
int main() {
std::ifstream in;
in.exceptions(std::ios::failbit);
try {
in.open("ghost_22222.txt");
} catch (const std::exception& e) {
std::cout << "caught open failure\n";
}
return 0;
}読み取り数を検証する
バイナリreadの後、gcount()は実際に読み取ったバイト数を返します。これにより、読み取り不足を検出できます。
#include <iostream>
#include <fstream>
int main() {
int v = 9;
std::ofstream("g.bin", std::ios::binary).write(reinterpret_cast<const char*>(&v), sizeof(v));
int out;
std::ifstream in("g.bin", std::ios::binary);
in.read(reinterpret_cast<char*>(&out), sizeof(out));
std::cout << "read " << in.gcount() << " bytes\n";
return 0;
}堅牢な読み取りループ
これまでの方法を組み合わせます。ループ内でストリームをテストし、終了後に正常終了とエラーを区別します。
#include <iostream>
#include <sstream>
int main() {
std::istringstream s("5 10 15");
int total = 0, x;
while (s >> x) total += x;
if (s.eof()) std::cout << "sum = " << total << " (clean)\n";
else std::cout << "error during read\n";
return 0;
}クイックチェック
ストリームの状態について理解度を確認しましょう。
まとめ
ストリームのエラー処理について、次のことを学びました。
- 状態フラグはgood/eof/fail/badで、各メソッドを使うか、ストリームをboolとしてテストして確認します
clear()は状態をリセットし、ignore()は不正な入力を破棄します- 正常な
eof()と実際のエラーを区別します。exceptions()で例外をスローでき、gcount()でバイナリ読み取りを検証できます
次のコースでは、<random>を使って乱数を生成します。
よくある質問
「エラー処理と状態」レッスンは無料ですか?
はい。「エラー処理と状態」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。
「エラー処理と状態」で何を学びますか?
ストリームの状態を確認します ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C++ Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「エラー処理と状態」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC++ Academyレッスンでコードを書いて実行できますか?
はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。