-2

Here is a program that takes a sequence of space-separated numbers and stores then in a vector. The problem is when putting the cin loop before the input of x0, the program jumps the next cin statement, but the reverse is working very normally.

Can you explain to me what I am missing here?

State of jump:

vector<int> V{};
int x0{}, temp{};
        
cout << "Enter sequence\n";
for(temp;cin>>temp;)
{
    if (!isalpha(temp)) V.push_back(temp);
    else
    {
        cin.clear();
        break;
    }
}
cout<<"enter x0 : ";
cin >> x0;// the program skips this!

The working reverse:

vector<int> V{};
int x0{}, temp{};
cout<<"enter x0 : ";
cin >> x0;
cout << "Enter sequence\n";
for(temp;cin>>temp;)
{
    if (!isalpha(temp)) V.push_back(temp);
    else
    {
        cin.clear();
        break;
    }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Hzine
  • 105
  • 1
  • 9
  • What do you expect to see in `temp` if a character is entered?? `if (!isalpha(temp))` is unlikely to become true. Also I suppose `cin>>temp` will always return `false` in that case. – πάντα ῥεῖ Feb 10 '21 at 22:02
  • temp is a temporary int variable to help push back the sequence in V, it could be used as for(int temp; cin>>temp;) – Hzine Feb 10 '21 at 22:05
  • 1
    I've seen that. The problem is that `temp` is `int` but you check if a `char` would have been entered. What you want is: https://stackoverflow.com/questions/24504582/how-to-test-whether-stringstream-operator-has-parsed-a-bad-type-and-skip-it – πάντα ῥεῖ Feb 10 '21 at 22:06
  • The problem here is that the second CIN>>x0 is not working, it is not assessed at all if I put the loop first, by reverse, if I put the cin>>x0 first, every thing works fine, so the question is about CIN>>x0 – Hzine Feb 10 '21 at 22:09
  • Check that link.above I already know what's going on in your code. It's the completely wrong approach for the problem. – πάντα ῥεῖ Feb 10 '21 at 22:10
  • Unrelated to your problem, but you can omit all parts of the `for` loop, you don't need the lonely `temp` in there: `for(;cin>>temp;)` is fine. – Some programmer dude Feb 10 '21 at 22:11
  • 3
    @Hzine The best way to grasp what your code actually does, is to step through line by line with the debugger, and check the variables' contents at each step. – πάντα ῥεῖ Feb 10 '21 at 22:16

1 Answers1

2

In the first example, you are calling cin >> temp in a loop until the read fails, either because a non-integer is entered, or the user explicitly ends input (with Ctrl-C or Ctrl-Z or whatever your platform uses). And then you are trying to call cin >> x0 without first clearing cin's error state, so that read will also fail.

Your call to cin.clear() (which does not discard data in cin's input buffer, only resets cin's error state) needs to be done after operator>> fails, not after the isalpha() check, eg:

vector<int> V;
int x0, temp;
        
cout << "Enter sequence\n";
do
{
    if (!(cin >> temp))
    {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        break;
    }

    if (isalpha(temp))
        break;

    V.push_back(temp);
}
while (true);

cout << "enter x0 : ";
cin >> x0;

In the second example, you are not trying to call cin >> x0 after a failed read, which is why that code works (provided that the user actually enters a valid integer for cin >> x0, otherwise cin >> temp will fail immediately since you are not resetting the error state or discarding data from the buffer).

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Sorry to say that it remains the same issue even if I copied your code, I know that the issue may reside in istream state ,but why it is not resetting again, I am using visual studio 2019 – Hzine Feb 12 '21 at 11:33
  • @Hzine what kind of input are you using to test with? What condition are you using to break the loop? – Remy Lebeau Feb 12 '21 at 13:39
  • a sequence like 1 2 3 1 2 3 1 2 3 E for an algorithm that detects repetition in a sequence starting from an element x0, I am using Floyd's algorithm . data are space separated and E defines the end of the sequence. – Hzine Feb 13 '21 at 13:33
  • 1
    @Hzine well, then the `isalpha()` check is useless since it will never return true. The `cin>>temp` will fail when `E` is reached, and the `ignore()` will swallow the `E`. You are passing only single-digit numbers to `isalpha()` that are never in the ASCII range for letters (65-90 and 97-122). If you want to do the `isalpha()` check, you should change `temp` from `int` to `char`, but then you will have to translate from `char` to `int` when pushing into the vector. Just get rid of `isalpha()`, it is not helping you. – Remy Lebeau Feb 13 '21 at 17:55
  • Mysteriously, I had more issues with my VS C++, so I repaired my VS2019 installation with setting the project standard to C++17, the code just run perfectly, I still don't know were was the issue, but I confirm that your code is working and my original is not. – Hzine Feb 13 '21 at 21:11