-1

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.

273K
  • 29,503
  • 10
  • 41
  • 64
  • 1
    The `peek` function doesn't extract the character it returns. So if one of the peeks turn out to be true then that character will be left in the input stream for your input of `in`, which will then fail. I suggest you read whole lines into a string, and parse the string instead. – Some programmer dude Feb 17 '23 at 07:36
  • And please don't use global variables. Pass arguments to your functions. And return values from the functions. – Some programmer dude Feb 17 '23 at 07:37
  • *"I am very new to C++"* -- This is a valid reason to not use `peek()`. That function can be confusing when you are learning the basics of the language. – JaMiT Feb 17 '23 at 07:50

1 Answers1

2

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.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82