C++ で単語ごとにファイルを読む
この記事では、C++ でファイルを単語ごとに読み取る方法に関する複数の方法を示します。
C++ で std::ifstream を使用して単語ごとにファイルを読み取る
std::ifstream クラスを使用して、ファイルベースのストリームの入力操作を実行できます。つまり、std::ifstream タイプは、ファイルバッファとインターフェイスし、抽出演算子を使用してファイルバッファを操作するために使用されます。std::fstream タイプは、抽出(>>)と挿入演算子(<<)の両方と互換性のある I/O ライブラリでも提供されることに注意してください。
最初に、コンストラクターの 1つを呼び出して、タイプ ifstream のオブジェクトを作成する必要があります。この場合、ファイル名文字列のみがコンストラクター関数に渡されます。ifstream オブジェクトが作成されたら、そのメソッドの 1つである is_open を呼び出して、呼び出しが成功したことを確認してから、ファイルの内容の読み取りに進む必要があります。
ファイルを単語ごとに読み取るために、ifstream オブジェクトで抽出演算子を呼び出します。文字列変数にリダイレクトします。文字列変数は、最初のスペース文字が検出される前に最初の単語を自動的に読み込みます。ファイルの終わりまで各単語を読み取る必要があるため、抽出ステートメントを while ループ式に挿入します。さらに、文字列のベクトルを宣言して、反復ごとに各単語を格納し、後で個別のループブロックで出力します。
#include <fstream>
#include <iostream>
#include <vector>
using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::string;
using std::vector;
int main() {
string filename("input.txt");
vector<string> words;
string word;
ifstream input_file(filename);
if (!input_file.is_open()) {
cerr << "Could not open the file - '" << filename << "'" << endl;
return EXIT_FAILURE;
}
while (input_file >> word) {
words.push_back(word);
}
for (const auto &i : words) {
cout << i << endl;
}
input_file.close();
return EXIT_SUCCESS;
}
C++ で std::ispunct および std::string::erase 関数を使用して句読点記号を解析する
前の方法の唯一の欠点は、宛先 vector の単語の近くに句読文字を格納することです。各単語を解析してから、ベクトルコンテナに保存することをお勧めします。単一の文字を int パラメーターとして受け取り、文字が句読点の場合はゼロ以外の整数値を返す ispunct 関数を使用しています。それ以外の場合は、ゼロが返されます。
指定された引数が unsigned char として表現できない場合、ispunct 関数の動作は定義されていないことに注意してください。したがって、文字を対応するタイプにキャストすることをお勧めします。次の例では、各単語の最初と最後の文字をチェックするために、2つの単純な if 条件を実装しました。句読点が見つかった場合は、組み込みの文字列関数 erase を呼び出して、見つかった文字を削除します。
#include <fstream>
#include <iostream>
#include <vector>
using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::string;
using std::vector;
int main() {
string filename("input.txt");
vector<string> words;
string word;
ifstream input_file(filename);
if (!input_file.is_open()) {
cerr << "Could not open the file - '" << filename << "'" << endl;
return EXIT_FAILURE;
}
while (input_file >> word) {
if (ispunct(static_cast<unsigned char>(word.back())))
word.erase(word.end() - 1);
else if (ispunct(static_cast<unsigned char>(word.front())))
word.erase(word.begin());
words.push_back(word);
}
for (const auto &i : words) {
cout << i << endl;
}
input_file.close();
return EXIT_SUCCESS;
}
