0

I just started with C++ 11 Primer book, and currently on the section of if statements. I have previous experience with Java, but C++ input/output is really confusing me. I am putting multiple exercises in one file, just for convenience sake. However, it seems like since I called while (cin >> p) it screws up my input for the question right below it.

I am using repel.it as my C++ code platform, and as such I am using a delimiter (!) to act as an end-of-file in my input for UNKOWN # OF INPUTS Section 1.4.3 question.

The problem occurs in Section 1.4.4, this line: if (std::cin >> currVal) {. It does not wait for input, and instead just regards it as no input and skips over the if statement. I tried moving the std::cin >> currVal out of the if statement to no avail (still does not read).

Here is an example input/output of my "program":

3825
10
9
8
7
6
5
4
3
2
1
Enter 2 Numbers: 
 6 9
6
7
8
9
0
3825
10
9
8
7
6
5
4
3
2
1
Enter as many numbers as you wish
 5 4 3 2 1 5!
20 

Here is my code:

#include <iostream>

int main() {
  //WHILE LOOPS Section 1.4.1
  //Exercise 1.9
  int sum = 0, i = 50;
  while (i <= 100) {
    sum += i;
    i++;
  }
  std::cout << sum << std::endl;
  //Exercise 1.10
  int j = 10;
  while (j > 0) {
    std::cout << j << std::endl;
    j--;
  }
  //Exercise 1.11
  int k, l;
  std::cout << "Enter 2 Numbers: " << std::endl;
  std::cin >> k >> l;
  while (k <= l) {
    std::cout << k << std::endl;
    k++;
  }
  //FOR LOOPS Section 1.4.2 
  //Exercise 1.12
  int sum1 = 0;
  for (int m = -100; m <= 100; ++m) {
    sum1 += m;
  }
  std::cout << sum1 << std::endl;
  //Exercise 1.13
  int sum2 = 0;
  for (int n = 50; n <= 100; n++) {
    sum2 += n;
  }
  std::cout << sum2 << std::endl;
  for (int o = 10; o > 0; o--) {
    std::cout << o << std::endl;
  }
  //UNKOWN # OF INPUTS Section 1.4.3
  //Exercise 1.16
  std::cout << "Enter as many numbers as you wish" << std::endl;
  int sum3 = 0, p = 0;
  while (std::cin >> p) {
    sum3 += p;
  }
  std::cout << sum3;
  //If Statement Section 1.4.4
  int currVal = 0, val = 0;
  if (std::cin >> currVal) {
    int cnt = 1;
    while (std::cin >> val) {
      if (val == currVal) {
        cnt++;
      } else {
        std::cout << currVal << " has occured " << cnt << " times." << std::endl;
        cnt = 0;
      }
    }
    std::cout << currVal << " has occured " << cnt << " times." << std::endl;
  }
  return 0;
}
George Jones
  • 245
  • 2
  • 11
  • `while (std::cin >> p) {` how do you break out of this loop when the program is running? Do you perchance send the EOF character? – scohe001 Mar 22 '18 at 00:41
  • @scohe001 so the C++ Primer books to do Ctrl + Z then enter, however repl.it uses the Ctrl + Z as "Cancel current prompt". I googled a bit, and found if I do a non integer it will work as one. That may be causing the problem, but what would I do as a replacement? – George Jones Mar 22 '18 at 00:45
  • I'm not sure if it's the same on windows, but in a bash shell, ctrl-D will send EOF, which will kill that loop. Of course, any of these ways will set cin's fail bit, which is exactly you're issue...this is almost definitely a duplicate, I just can't find a good link. – scohe001 Mar 22 '18 at 00:51
  • See the second answer [here](https://stackoverflow.com/questions/11095291/reusing-stdcin-after-eof), or top two answers [here](https://stackoverflow.com/questions/5864540/infinite-loop-with-cin-when-typing-string-while-a-number-is-expected). I think this answer is the closest to your question though: [here](https://stackoverflow.com/questions/29818585/after-enter-eof-cannot-reuse-cin-to-read-values). – scohe001 Mar 22 '18 at 00:53
  • `while (std::cin >> p) {` -- the `while` loop terminates when the formatted extraction operator, `>>`, fails. This sets `std::cin` in failed state. All subsequent operation on `std::cin` will fail immediately, from that point out, until the error state gets explicitly cleared. That's why the subsequent `if` doesn't do anything. It's `>>` operator fails immediately, because `std::cin` is in failed state. – Sam Varshavchik Mar 22 '18 at 00:53
  • thanks for the explanation, I understand now. However, I am still confused what I am supposed to do in replacement of an invalid character. I know I can reset it via cout.clear(), but does anyone know a possible way to do it on repl.it the proper way like Ctrl D on UNIX? – George Jones Mar 22 '18 at 01:00
  • update: std::cin.out() still does not clear the error. – George Jones Mar 22 '18 at 01:07

1 Answers1

1

Try implementing the loop exit yourself. I.e. replace

  int sum3 = 0, p = 0;

  [...]

  while (std::cin >> p) {
    sum3 += p;
  }

by

  int sum3 = 0, p_;
  string p;

  [...]

  while (std::cin >> p) {


      if ( p == "exit" )
          break;

      stringstream convert(p);

      if ( convert >> p_ )
          sum3 += atof(p_);

      else
          std::cout << "Invalid number supplied!" << std::endl;
  }

Now you can just type "exit" and send it as if it were a number, instead of sending some EOF character that may 'break' std::cin and set it to failed.

Make sure you also #include <sstream> so that the stringstream string to int conversion is available.

wallabra
  • 412
  • 8
  • 17