通过ifstream对象

时间:2017-10-26 08:42:11

标签: c++

我有一个用ifstream对象读取文件的程序。

#include <iostream>
#include <fstream>
#include <string>

using namespace std;


struct FPlayerInfo
{
    string name;
    string pos;
    int numTouchDowns;
    int numCatches;
    int numPassingYards;
    int numReceivingYards;
    int numRushingYards;
};


void loadInfo(FPlayerInfo info[10], string filename)
{
    int i=0;
    ifstream ifs(filename.c_str() , ios::in);

    if (ifs.good() && ifs.is_open())
    {
        string line;
        while (getline(ifs, line))
        {
            ifs >> info[i].name >> info[i].pos >> info[i].numTouchDowns >> info[i].numCatches >> info[i].numPassingYards 
                >> info[i].numReceivingYards >> info[i].numRushingYards;

            cout << info[i].name << endl;
            i++;
        }

        ifs.close();
    }
}

int main()
{
    FPlayerInfo info[10];

    loadInfo(info , "Footballdata.txt"); 

    return 0;  
}

Footballdata.txt包含以下数据:

Bill Quarter_Back 70 0 8754 0 573
Jackson Receiver 55 87 50 5490 574
Grahm Running_Back 45 30 0 50 2800
McCoy Full_Back 25 10 0 25 3762
Daryl Quarter_Back 50 2 7560 0 450
Santiago Left_Tackle 5 0 0 0 0
Hanks Receiver 35 37 0 3590 876
Johnson Running_Back 25 80 0 100 4000
Miller Receiver 110 250 150 7867 2100
Ruth Quarter_Back 85 0 12901 0 3249

执行上述程序后,我希望在输出中返回所有名称。但我观察到的是实际输出中缺少第一个名称,最后一行我变得空白。任何人都可以告诉我在阅读文件时我犯了什么错误吗?

提前致谢。

实际输出:

Jackson
Grahm
McCoy
Daryl
Santiago
Hanks
Johnson
Miller
Ruth

1 个答案:

答案 0 :(得分:1)

getline从输入中读取一行 然后ifs >> info[i].name >> ..读取其他信息,从而使用getline跳过您所阅读的内容。

简单地改变:

string line;
while (getline(ifs, line))
{
    ifs >> info[i].name >> info[i].pos >> info[i].numTouchDowns >> info[i].numCatches >> info[i].numPassingYards 
        >> info[i].numReceivingYards >> info[i].numRushingYards;
    [..]
}

分为:

while (true)
{
    ifs >> info[i].name >> info[i].pos >> info[i].numTouchDowns >> info[i].numCatches >> info[i].numPassingYards 
        >> info[i].numReceivingYards >> info[i].numRushingYards;
    if (!ifs) break;
    [..]
}

更好的实现(拆分以避免乱丢实际问题),使用临时对象并在我们意识到读取成功后移动它:

while (true)
{
    FPlayerInfo temp;
    ifs >> temp.name >> temp.pos >> temp.numTouchDowns >> temp.numCatches >> temp.numPassingYards 
        >> temp.numReceivingYards >> temp.numRushingYards;
    if (!ifs) break;

    info[i] = std::move(temp);
    [..]
}