0

I want to read in scores from a txt file. The scores are going into a struct.

struct playerScore
{
    char name[32];
    int score, difficulty;
    float time;
};

the text file looks like this

Seth 26.255 40 7

as one line, where each item is followed by a tab. (Name\t time\t score\t difficulty\n)

When I begin to read in the text, I don't know how to tell the program when to stop. The scores file could be any number of lines or score entries. This is what I have attempted.

hs.open("scores.txt", ios_base::in);
hs.seekg(0, hs.beg);


if (hs.is_open())
    {
        int currpos = 0;
        while (int(hs.tellg()) != int(hs.end));
        {
                hs>> inScore.name;
                hs >> inScore.time;
                hs >> inScore.score;
                hs >> inScore.difficulty;
                hs.ignore(INT_MAX, '\n');
                AllScores.push_back(inScore);
                currpos = (int)hs.tellg();
        }
    }

I'm trying to make a loop that will read in a line of code into a temp struct for the data, then push that struct into a vector of structs. Then update the currpos variable with the current location of the input pointer. However, the loop just gets stuck on the condition and freezes.

user3334986
  • 149
  • 11

3 Answers3

1

There are a multitude of ways to do this, but the following is likely what you're looking for. Declare a free-operator for extracting a single-line definition of a player-score:

std::istream& operator >>(std::istream& inf, playerScore& ps)
{
    // read a single line.
    std::string line;
    if (std::getline(inf, line))
    {
        // use a string stream to parse line by line.
        std::istringstream iss(line);
        if (!(iss.getline(ps.name, sizeof(ps.name)/sizeof(*ps.name), '\t') &&
             (iss >> ps.time >> ps.score >> ps.difficulty)))
        {
            // fails to parse a full record. set the top-stream fail-bit.
            inf.setstate(std::ios::failbit);
        }
    }
    return inf;
}

With that, your read code can now do this:

std::istream_iterator<playerScore> hs_it(hs), hs_eof;
std::vector<playerScore> scores(hs_it, hs_eof);
WhozCraig
  • 59,130
  • 9
  • 69
  • 128
0

I dont think that you can just >> from your file. Do you think it will take everything till \t? :)

You can try to take for example token with strtok() I guess it can use '\t' to split string and take for each variable via this function needed part of string In case if it strtok() doesnt work that way i guess you can just copy till '\t' in sub-loop

Douman
  • 66
  • 7
0

You can do like this

playerScore s1;

fstream file;
file.open("scores.txt", ios::in | ios::out);
while(!file.eof()) //For end of while loop
{
    file.read(s1, sizeof(playerScore));//read data in one structure.
    AllScores.push_back(s1);
}
EmptyData
  • 2,086
  • 2
  • 22
  • 36
  • Whoever told you `while (!file.eof())` is the right way to do this, kindly [**tell them they're wrong.**](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). Looping on `std::istream::eof` is quite literally wrong in 99.99% of the cases it is done. (and this isn't the 0.01% exception to that). Ask yourself. How do you know that `file.read()` *worked* before blindly assuming it did and pushing `s1` into the container? – WhozCraig Mar 20 '14 at 05:51