1

Please need help with this problem. When I run the executable file, the console is not giving me time to enter the characters as requested in line 37 and I'm not able to identify the issue. It only works when I comment out both for-loops. The code is shown below:

#include "../../std_lib_facilities.h"
#include "../../Eigen/Eigen"
#include "../../Eigen/Dense"
#include <Windows.h>
#include <time.h>

using namespace Eigen;

int main()
{
    SetConsoleTitle(TEXT("PipeThk_v1.0"));
    system("CLS");
    system("color F1");
    time_t rawtime_start;
    struct tm * timeinfo_start;
    time(&rawtime_start);
    timeinfo_start = localtime(&rawtime_start);
    printf(asctime(timeinfo_start));

    cout << "\nEnter nominal pipe sizes in 'in':\n";
    vector<double> npss;
    for (double nps; cin >> nps;)
    npss.push_back(nps);

    cout << "\n NPS\n";
    for (const auto& i : npss)
    cout << "\n " << i;

    time_t rawtime_end;
    struct tm * timeinfo_end;
    time(&rawtime_end);
    timeinfo_end = localtime(&rawtime_end);
    cout << endl << endl << asctime(timeinfo_end);

    cout << "\nEnter any character and hit enter to exit:\n";
    char ans;
    cin >> ans;

    return 0;
}
Steve Fallows
  • 6,274
  • 5
  • 47
  • 67
PipeTran
  • 13
  • 2
  • 1
    Not your issue, but you don't need to have `cin` wait on a `char`, you can simply use `std::cin.get();` – Tas Jul 12 '16 at 01:46
  • Use `System("pause");` instead of your 35, 36 and 37 if you are on Windows but see [**here**](http://stackoverflow.com/questions/1107705/systempause-why-is-it-wrong) why it is not recommended – Khalil Khalaf Jul 12 '16 at 01:47
  • Possible duplicate of: http://stackoverflow.com/questions/10553597/cin-and-getline-skipping-input – Amir Kirsh Jul 12 '16 at 01:55

1 Answers1

3

You are using operator>> to parse std::cin into a double variable.

operator>> stops reading input when it encounters a character that cannot be converted. That character, such as when pressing Enter or Space, will remain in the stream's buffer and be immediately available to be read by operator>> on line 37 without any need to prompt the user for more input.

So, for example, if you entered 47 and pressed Enter for the last double value, the value 47 gets parsed into your double variable, and the Enter key gets read as a \n character by std::cin >> ans.

The lesson for today is: do not use operator>> to process interactive input from std::cin from the terminal. Use std::getline() to read one line of text at a time, an then construct a std::istringstream object to parse the line as needed. Replace every occurence of std::cin >> ... with std::getline(std::cin) in order to avoid unexpected surprises with parsing interactive input.

That, of course, is not the only way to do it, but the one that requires the least amount of work, and results in the least amount of unexpected behavior.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • There is nothing wrong with using `operator>>` to read input from `std::cin` directly. You just have to clear its buffer to flush out any pending data before reading the last `char` so it will wait on the user, eg: `cin.clear(); cin.ignore(numeric_limits::max(), '\n'); cin >> ans /*or cin.get()*/;` – Remy Lebeau Jul 12 '16 at 01:53
  • I followed the flushing out buffer solution because I don't see any other cleaner way for collecting the data for my `npss` vector without the `operator>>`. Also I had to use `cin.ignore(10000, '\n')` instead because I was getting some error message about expected and identifier under the max() part. @Remy Lebeau can you comment on it? – PipeTran Jul 12 '16 at 04:14
  • @PipeTran Sam gave you a cleaner solution - use `std::getline()` to read lines and `std::istringstream` to parse each line. You can use `operator>>` on `std::istringstream`. As for the `numeric_limits` error, use `#include `. – Remy Lebeau Jul 12 '16 at 06:40