I'm trying to get a better understanding of ifstream, and was playing with it using the program below. It's purpose was to grab the first and last entries in the file, instead I get some perplexing output leading me to realize I've very little clue as to how streams really work. I know the simple book nuts and bolts, but putting it into practice is different. (and yes I am avoiding .eof() on purpose)

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream names;
    names.open("P25.txt");

    string firstInFile;
    string lastInFile;
    string next;
    string students;


    while(names >> students)
    {
        names >> firstInFile;
        names >> lastInFile;
    }

    names.close();

    cout << firstInFile << endl;
    cout << lastInFile << endl;


    return 0;
}


/*
P25.txt
-------
Amy
Angela
Vicky
KC
Stephanie
Mark
Andrea
Tom
*/

What I'm getting in output is:
Tom
Mark

If I change the code a little like this:

    names >> firstInFile;

    while(names >> students)
    {

        names >> lastInFile;
    }

The output is :
Amy
Andrea

I get Amy, as it's the first entry in the file, but why does it stop at Andrea, when there is one more entry it can read in.

Also,
If I just have this:

 while(names >> students)
        {

            names >> lastInFile;
        }

With no other reading, it does indeed return the last entry in the file.

I know this is a pretty simple question, but I'm really trying to get a decent grasp on what's going on.

I added a counter to trying and gauge where the read head is:

/*
25. Using Files Student Line Up
Modify the Student Line Up program described in Programming Challenge 14 so that
it gets the names from a file. Names should be read in until there is no more data to
read. If you have downloaded this books source code from the companion Web site,
you will nd a le named LineUp.txt in the Chapter 05 folder. You can use this le to
test the program. (The companion Web site is at www.pearsonhighered.com/gaddis.)
*/

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream names;
    names.open("P25.txt");

    string firstInFile;
    string lastInFile;
    int i = 0;
    string students;
    i++;
    names >> firstInFile;
 names.close();
 names.open("P25.txt");
    while(names >> students)
    {
        names >> lastInFile;
        i++;
    }

    names.close();

    cout << firstInFile << endl;
    cout << lastInFile << endl;
    cout << i << endl;


    return 0;
}


/*
P25.txt
-------
Amy
Angela
Vicky
KC
Stephanie
Mark
Andrea
Tom
*/

and this is my output:
Amy
Tom
5

Process returned 0 (0x0) execution time : 0.047 s
Press any key to continue.

Why is it at 5? Arg, this is so confusing.

Try running this program with your data.

#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char** argv) 
{
    ifstream names;

    names.open("P25.txt");

    string data;

    while(names >> data)
    {
        cout << "You read->" << data << "<-into data!" << std::endl;
    }

    names.close();

    return 0;
}

I actually tried that, and for somereason nothing is displayed. I'm using codeblocks, though I'm not sure if that has anything to do with it.

Did you pass std::endl or "\n" to std::cout?

I cut and pasted your code. Which from what I can see should work, or at least spit somthing out. This is literally what's in my text file:

Amy
Angela
Vicky
KC
Stephanie
Mark
Andrea
Tom

Are you sure the datafile is in the same folder as the executable.

Yeah, I am able to run the code I posted above just fine.

Why is it at 5? Arg, this is so confusing.

Because you are reading two names per iteration when you do this:

while(names >> students)
{
    names >> lastInFile;
    i++;
}

You read one name into students and then another into lastInFile. Because you have 8 names, and you first read one before the loop, you then get 7 names to read in the loop, which takes 4 iterations. This is why you get 5 printed out (1 + 4). You need to read only one name per iteration:

while(names >> lastInFile)
{
    i++;
}

and that should give you the correct result (8) for the counter, and lastInFile should contain the last valid name from the file.

AHA! That makes total sense, in the while it's acutually performing the function, FACE PALM (to self stoopid rookie!) Thanks Mike_2000_17.

Though I'm not sure why I can't ghet gerad4143's code to work. I'll keep playing with, my big question was answered. Thanks guys!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.