1

I am reading the book 'Accelerated C++', and I am unable to reproduce the results for their read homework problem even after exactly copying their code on my machine. The basic problem is about using cin.clear() to change the failure state of the inpute stream after the use of EOF to indicate that all the grades have been entered. Authors suggest Ctrl+D on linux systems for EOF. I already saw this and this but they couldn't solve my problem.

Here is my minimal working example:

#include <iostream>
#include <string>
#include <vector>

using namespace std;
int main()
{
    string name, city;
    vector<double> homework;
    cout << "Enter your name : " ;
    cin >> name;
    cout << "Hello " + name + "!" << endl;
    cout << endl;
    cout << "Enter your grades" << endl;
    if (cin)
    {
        homework.clear();
        double x;
        while (cin >> x)
        {
            homework.push_back(x);
        }
        cin.clear();
    }
    cout << endl;
    cout << "Enter your city : " ;
    cin >> city ; 
    cout << "You live in " + city << endl;; 
    return 0;
}

After entering all the homework, I hit Ctrl+D and then I expect that I would now be given chance to enter city name. But the program just ends after printing the two strings at the end of my code. What is wrong with my understanding of cin.clear()? I would also like to point out that using cin.ignore() after cin.clear() doesn't help either.

Peaceful
  • 4,920
  • 15
  • 54
  • 79
  • @SamVarshavchik Could you please tell me one? I badly need to learn C++ fast. – Peaceful Apr 17 '20 at 02:25
  • Do you need to pass some exam or learn c++? This exercise (or example) is contrived, you don't have to use EOF as end of grades, if it causes trouble. Use whatever does work, keep progressing. – ddbug Apr 17 '20 at 02:34
  • @ddbug Not exam. I need to rewrite a large number of fortran legacy codes in C++ and I have something like 1 year of time with me. – Peaceful Apr 17 '20 at 02:39
  • @ddbug What is the exact problem with the code though, and what is the solution? Could you also recommend me a good resource? – Peaceful Apr 17 '20 at 02:42
  • 1
    Sorry, don't know any book that helps instantly (( The problem IMHO is that EOF (ctrl/D in Linux) renders `cin` unusable TL;DR.So avoid it. For example, instruct the user to input 0 or negative number as end of grades. Then just keep reading further data. First make it work, only then make cosmetic improvements. – ddbug Apr 17 '20 at 02:49
  • @ddbug Thanks so much. I would be grateful if you could tell me an up to date and a good resource to learn C++ – Peaceful Apr 17 '20 at 02:53
  • 1
    @Peaceful If you want to learn how to write good, modern `C++` use PluralSight and take any of the courses by Kate Gregory – WBuck Apr 17 '20 at 03:03

1 Answers1

1

On fail you need to clear the flags and ignore all the bad input.

Include #include <limits> for std::numeric_limits.

    if ( std::cin.fail( ) )
    {
        std::cin.clear( );
        std::cin.ignore( std::numeric_limits<std::streamsize>::max( ), '\n');
    }

If you want a way to exit the loop use a value that you can test for (like -1). When you receive that value, exit the loop.

double value{ 0 };
while( std::cin >> value && value != -1 )
    homework.push_back( value );

if ( std::cin.fail( ) )
{
    std::cin.clear( );
    std::cin.ignore( std::numeric_limits<std::streamsize>::max( ), '\n');
}

Edit:

I didn't see that you were trying to end the stream with EOF. Read this answer to figure out how to accomplish this.

How to resume input stream after stopped by EOF in C++?

WBuck
  • 5,162
  • 2
  • 25
  • 36