Search code examples
c++for-loopcinpeek

Why does cin.peek() == '\n' work for '+' and '-', but not for '*', '/', and '^'?


I'm doing a calculator in replit. Why does my cin.peek() == '\n' work when I enter + and - but it doesn't work when I enter *, /, or ^?

#include <iostream>
#include <math.h>
#include <vector>
#include <istream>
using namespace std;

float hasil;
vector<float> num;
vector<char> op;

void calc(float x, float y, char z) {
  if (z == '+') {
   hasil = x + y;
    }
  else if (z == '-') {
    hasil = x - y;
  }
  else if (z == '*') {
    hasil = x * y;
  }
  else if (z == '/') {
    hasil = x / y;
  }
  else if (z == '^') {
    hasil = pow(x,y);
  }
  else {
    cout<< "wrong operator";
   }
  }
void input () {
  float in;
  char ch;
 for (int i = 0;;i++) {
   if(cin.peek() == '\n') {
     break;
    }
   else if(cin.peek() == '+') {
   op.push_back('+');
    }
   else if(cin.peek() == '-') {
   op.push_back('+');
    }
   else if(cin.peek() == '*') {
   op.push_back('*');
    }
   else if(cin.peek() == '/') {
   op.push_back('/');
    }
   else if(cin.peek() == '^') {
   op.push_back('^');
     }
   cin >> in;
   num.push_back(in);
  }
  for (auto i = num.begin(); i != num.end(); ++i) {
    cout << *i << " ";
  }
  for (auto i = op.begin(); i != op.end(); ++i) { //this is just so I can see what is in the vectors
    cout << *i << " ";
  }
  calc(num.at(0),num.at(1),op.at(0));
  for (int i = 2; i < num.size(); i++)
    calc(hasil,num.at(i),op.at(i-1));
}
int main() {
  cout << "rumus = ";
  input();
  cout << " = ";
  cout << hasil;
}

When I enter 1+2+3+4 it works fine, but the for loop doesn't break when I, for example, enter 1/3 or 2/3.

    if(cin.peek() == '\n') {
     break;
    }

Why doesn't this run when there is a /, *, or ^ in what I enter?

Sorry if I have bad grammar. English is not my first language, and I am very new to C++ and coding in general. I don't know much about coding.


Solution

  • If you enter "4-2", you might notice that the numbers are 4 and -2, and the operator is +.
    It produces the correct result by mistake because of if(cin.peek() == '-') { op.push_back('+'). (Copy-paste bug?)

    You never actually read an operator, you only read floats.
    "+2" and "-2" are valid inputs when reading a number, and peek leaves the character in the stream.
    Thus, "1+2" is read as "1" and "+2", "1-2" as "1" and "-2".

    None of the other operators can prefix a number, so in all those cases the stream enters an error state, never reads anything, and you're stuck in a loop.

    I will leave fixing the bug as an exercise.