1. ホーム
  2. c++

[解決済み] getline() を使用してファイルから複数行を読み込む

2022-02-27 06:20:52

質問

以下のような3行のテキストファイルの内容を読み込んで、出力しようとしています。

ボブ・ディラン 10 9

ジョン・レノン 8 7

デヴィッド・ボウイ 6 5

各行に対して、firstName LastName number1 number2というように、行を出力したいだけなのです。

これには、以下のコードを使用しています。

int num1;
int num2;
string firstName;
string lastName;
string fullName; 
ifstream inFile;

inFile.open("inputFile.txt");

while (getline(inFile, firstName))
    {
        inFile >> firstName >> lastName >> num1 >> num2;

        fullName = firstName + " " + lastName;

        cout << fullName << " " << num1 << " " << num2 << endl;
    }

inFile.close();

これの出力には2つの問題があります。まず、最初の行は出力されませんが、実験の結果、それは読み込まれることが分かっています。第二に、最後の2行が読み込まれて出力された後、プログラムは最後の行のファーストネーム以外のすべてを表示します(この場合、最後に出力されるのはBowie 6 5です)。

誰かこの簡単な例を使って、ファイルから複数行を読み込むときに getline 関数がどのように動作するかを説明できますか?(これが最良の方法かどうかも分かりませんが、今のところ私が知っている唯一の方法です)。以下は具体的な質問です。

まず、whileループの条件であるgetline(inFile, firstName)はbooleanを返すのでしょうか?もしそうなら、firstNameにまだ値を与えていないのに、どうしてそれが真になるのでしょうか(つまり、どうしてwhileループが開始されるのでしょうか)?プログラムは最初の行を読み、そこに何かがあれば、2行目からwhileループを実行しますが、最初の行はすでに内容をチェックするために使用されているからです。

次に、もしfirstNameが値を持ち、その値が1行目の名前(この場合は"Bob")であるなら、なぜ1行目が全く出力されないのでしょうか?私はそれがどこに行ったのかを理解するために頭を悩ませています。

第三に、プログラムは最後の2行を読み込んで表示した後、次の行に移動して空白にしか遭遇しませんよね?そうすると、firstNameの値はどうなるのでしょうか?空白でしょうか、それともやはり "David"なのでしょうか?もし空白なら、なぜwhileループは再び実行されるのでしょうか?しかし、もしそれが "David" であるなら、なぜプログラムはその値を他の値と一緒に出力しないのでしょうか?

Btw, 私は教科書(宿題用ではない)を使って作業しているのですが、getlineは取り上げていますが、複数行の場合は取り上げていません。しかし、練習問題では複数行を含むので、少し迷っています。

どのように解決するのですか?

各行を2回読もうとしている。

while (getline(inFile, firstName)) // reads the line
    {
        // reads the next line and overwrites firstName!
        inFile >> firstName >> lastName >> num1 >> num2;

に変更します。

while ( inFile >> firstName >> lastName >> num1 >> num2 )
{
    fullName = firstName + " " + lastName;
    cout << fullName << " " << num1 << " " << num2 << endl;
}

編集部:質問にお答えします。

getline() はどのように動作するのですか?
'\n' 文字または指定された区切り文字まで行全体を読み込みます。 http://www.cplusplus.com/reference/string/string/getline/?kw=getline

行を読み込んだ後、コントロールはファイルの次の行に進みます。
また、読み取り操作が成功した場合はtrue、そうでない場合はfalseのブール値を返します。

抽出演算子は、デフォルトですべてのホワイトスペースで切り捨てられます。また、操作が成功したかどうかを示すブーリアン値も返します。