How do I stop ..eof from reading the last line of input twice?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <queue>
using namespace std;
int main () {
    int n, num, cust;
    char type;
    cin>>n;
    queue <int> q;
    vector <int> desk[10];
    while (!cin.eof()) {
        cin>>type>>num;
        if (type=='C')
        q.push(num);
        else if (type=='D'){
            int cust=q.front();
            q.pop();
            desk[num].push_back(cust);
        }
    }
    for (int i=1; i<=n; i++) {
        for (int j=0; j<desk[i].size(); j++) {
            cout<<desk[i][j]<<" ";
        }
        cout<<endl;
    }
}
Check for input failure after (not before) attempted input.

Canonical:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

int main()
{
    int num ;
    char type ;

    while( std::cin >> type >> num ) {

        std::cout << "type: " << type << "   number: " << num << '\n' ;

        // do whatever with type and num
    }
}
Protip: as of C++11, you can loop on stream extraction operations, like so:
1
2
3
while(cin >> something) {
    //Code in here only runs if the read in the condition of the loop succeeded.
}


This prevents mistakes wherein someone reads stuff from std::cin but doesn't check whether the read operation succeeded or not, and proceeds through their code using the data that was in their buffer variables from the last run of the loop.

-Albatross

P.S:
cppreference wrote:
[eof()] only reports the stream state as set by the most recent I/O operation; it does not examine the associated data source. For example, if the most recent I/O was a get() which returned the last byte of a file, eof() returns false.
Last edited on
as of C++11, you can loop on stream extraction operations, like so

Couldn't you do that pre C++11 too?
My mistake, you definitely could (though the way they went around making that possible was a bit strange).

-Albatross
> though the way they went around making that possible was a bit strange

Jerry Schwarz did not have much of a choice.

Prior to C++11, the language did not support explicit specifiers for conversion functions;
and the design goal was that a typo like std::cin << x should be caught at compile time.
Voila! operator void*() const;
The safe-bool idiom (that is, operator void* in this context) also protects against a number of other mistakes arising from unwanted implicit conversions:
https://www.artima.com/cppsource/safebool.html
Last edited on
No, I get its purpose, but it still feels like the sort of thing that they could have made unnecessary when C++98 was being put together.

All well, I guess C++98 was, among other things, the language that required us to put spaces between the closing brackets of template argument lists.

-Albatross
Topic archived. No new replies allowed.