次のコマンド ライン引数を取るプログラムを作成する演習を完了しようとしています: 入力ファイル、出力ファイル、および指定されていない単語数。このプログラムは、入力ファイルの内容を 1 行ずつ読み取り、その単語が含まれる行を指定して各単語を検索し、その行を行番号と共に出力ファイルに出力します。これが私のコードです:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
int main(int argc, char* argv[]) {
if (argc < 4) {
cerr << "Error #1: not enough arguments provided\n";
return 1;
}
ifstream in(argv[1]);
if (!in.is_open()) {
cerr << "Error #2: input file could not be opened\n";
return 2;
}
ofstream out(argv[2]);
if (!out.is_open()) {
cerr << "Error #3: output file could not be opened\n";
return 3;
}
ostringstream oss;
for (int i = 3; i < argc; ++i) {
int k = 0;
string temp;
oss << argv[i] << ":\n\n";
while (getline(in, temp)) {
++k;
unsigned x = temp.find(argv[i]);
if (x != string::npos)
oss << "Line #" << k << ": " << temp << endl;
}
}
string copy = oss.str();
out << copy;
in.close();
out.close();
return 0;
}
それを実行しようとすると、指定された最初の単語の予測出力が得られますが、その後の単語は見つかりません。たとえば、上記のソース コードの場合、次の出力が得られます。
in:
Line #1: #include <iostream>
Line #2: #include <fstream>
Line #3: #include <string>
Line #4: #include <sstream>
Line #5: using namespace std;
Line #7: int main(int argc, char* argv[]) {
Line #12: ifstream in(argv[1]);
Line #13: if (!in.is_open()) {
Line #14: cerr << "Error #2: input file could not be opened\n";
Line #22: ostringstream oss;
Line #23: string temp;
Line #24: for (int i = 3; i < argc; ++i) {
Line #26: int k = 0;
Line #28: while (getline(in, temp)) {
Line #30: unsigned x = temp.find(argv[i]);
Line #31: if (x != string::npos)
Line #32: oss << "Line #" << k << ": " << temp << endl;
Line #35: string copy = oss.str();
Line #37: in.close();
out:
つまり、指定された最初の単語のすべてのインスタンスが検索されますが、後続の単語は検索されません。ここで何が間違っていますか?
編集:ファイルの先頭に戻る方法を見つけようとしていましたが、「rewind()」などと呼ばれるメソッドが見つからなかったため、あきらめました。while ループの後に追加しましin.seekg(0, ios::beg)
たが、それでも同じ間違った出力が得られます。
EDIT 2:さて、私は最終的にあきらめて、ペアのベクトルを使用するためのある種のワイルドな試みなしでは、元の目的の出力を取得できないことに気付いたので、あきらめて、この形式で印刷することにしました:
found in at line #31: cerr << "Error #2: input file could not be opened\n";
found out at line #34: ofstream out(argv[2]);
つまり、すべての行を順番に出力し、見つかった特定の単語を各行の先頭に付けます。while ループは次のとおりです。
ostringstream oss;
string temp;
while(getline(in,temp)) {
static int count = 1;
for (int i = 3; i < argc; ++i) {
unsigned foundWord = temp.find(argv[i]);
if (foundWord != string::npos)
oss << "found " << argv[i] << " at line #" << count << ": " << temp << endl;
}
++count;
}
とにかく、すべての助けをありがとう!演習自体は、出力を何らかの方法でフォーマットする必要があるとは言っていないので、完全に完了したと考えています。