Issue with loop repeating one more time than it should - c++

#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int main()
{
char terminate;
double a, b, answer;
char operators;
cout << "Please enter your expression: ";
terminate = cin.peek();
cin >> a >> operators >> b;
while (terminate != 'q')
{
switch(operators)
{
case '+':
answer = a + b;
break;
case '-':
answer = a - b;
break;
case '*':
answer = a * b;
break;
case '/':
answer = a / b;
break;
case '^':
answer = pow(a,b);
break;
}
cout << a << " " << operators << " " << b << " = " << answer << endl;
cout << "Please enter your expression: ";
cin.clear();
terminate = cin.peek();
cin >> a >> operators >> b;
}
return 0;
}
This is my simple calculator program, it is meant to repeat and ask the user to enter a binary expression until the value "q" is entered, however upon entering "q" the while loop still executes once more even though the variable terminate has the value of "q". I don't understand why it is doing this, any help would be appreciated. Thanks

Let us take a look at an example of what is happening with this input:
1 + 1 Enter
terminate = cin.peek();
This line will peek into the buffer, read what is there but it will not remove it from the buffer
cin >> a >> operators >> b;
This line will read 1 + 1 and store it in a operators b and remove those characters from the buffer
Now what you have left is the Enter key which is still in the buffer and it will be read the next time you try and read the buffer and this is where you issue is as the next time you call terminate = cin.peek(); you get the \n and not the q that you expect
I noticed that you might have tried to fix that issue by calling std::cin::clear but that is not what that function does. That functions resets the iostate flags and that is not what you are looking for. If you want to clear the buffer then you have to call std::cin::ignore

Related

How do you make a calculator in c++ using switch case and while loop?

The calculator is made to run once using the switch case but i wanted to use while loop for if you type a wrong operator it wouldn't restart all over again but just ask you to retype the correct operator and then loop again until you quit.
float z,y,z;
char err 'c',opp;
while (err !='q')
{
cout<<"enter value for x ";
cin>>x;
cout<<"enter value for y ";
cin>>y;
cout<<"enter + for addition";
cout<<"enter - for subtraction";
cout<<"enter * for multiplication";
same for divison
cout<<"enter r to restart"<<endl;
cout<<"enter q to quit"<<endl;
cin>>opp;
err = 'u';
switch(opp)
and then you get the case and break for all the operators, for restart and quit,
case 'r'
cout<<"restarting "<<endl;
break;
case 'q'
cout<<"quitting "<<endl;
err ='q';
break;
but how do i made it loop using a while loop so it doesn't make me repeat the values but just asks me to retype the operator?
I'm sorry, but i didn't write this code, a teacher of min did, he asked us to use exactly what he typed but use while loop, he asked us not to change x, y or z or anything and i know he didn't initialize err and I'm so confused, i don't understand the code
This homework shall teach you how to do input validation.
The C++ iostream library will help you.
And, you must check always each IO operation for potential errors. For that reason streams, like std::cin have a state. You can acces this with the so called state functions. Please see here.
Especially useful are the operator! and the operator bool. They will show you, if the stream, after an IO operation is still in good state or not.
For example, if you open a file with std:istream ifs("text.txt);, then you can simply write if (!ifs) to detect an error or if (ifs) to see, if the result was good. This works with all stream operations.
Additionally, you can also write something like if (std::cin >> x) to check, if the user input was ok.
You may expect an integer, but the user will type "abc". This mechanisms works, because the extration operator >> returns again a reference to the stream. So, if (std::cin >> x) will end up similar like if (std::cin). And then the bool operator for the stream will be used to get the state.
For the other input validations, e.g., if an operator is valid, we can simply use boolean expressions. We embed everything in a loop and continue the loop, unitl we get a valid input.
The result could be a code like the below:
#include <iostream>
#include <limits>
int main() {
bool inputError = true;
bool doOperate = true;
while (doOperate) {
float x = 0;
float y = 0;
float z = 0;
char oper = '\0';
do {
std::cout << "\n\n\nPlease enter value for operand x: ";
inputError = not(std::cin >> x);
if (inputError) {
std::cout << "\nError: Problem with given input\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
} while (inputError);
do {
std::cout << "\nPlease enter value for operand y: ";
inputError = not(std::cin >> y);
if (inputError) {
std::cout << "\nError: Problem with given input\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
} while (inputError);
do {
std::cout << "\nPlease enter operator. Either + or - or * or /: ";
inputError = (not(std::cin >> oper) or (oper != '+' and oper != '-' and oper != '*' and oper != '/'));
if (inputError) {
std::cout << "\nError: Problem with given input\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
} while (inputError);
switch (oper) {
case '+':
std::cout << "\n\nThe result of x + y = " << (x + y) << '\n';
break;
case '-':
std::cout << "\n\nThe result of x - y = " << (x - y) << '\n';
break;
case '*':
std::cout << "\n\nThe result of x * y = " << (x * y) << '\n';
break;
case '/':
if (y == 0)
std::cout << "\n\nError: Division by 0 not allowed\n";
else
std::cout << "\n\nThe result of x / y = " << (x / y) << '\n';
break;
default:
std::cerr << "\n\nError: Internal Error. Stopping program . . .";
doOperate = false;
break;
}
std::cout << "\n\n\nDo you want to continue? Then enter y\n";
char selection = '\0';
if (not((std::cin >> selection) and (selection == 'y')))
doOperate = false;
}
std::cout << "\n\nLeaving program . . .\n\n";
}
Please note: Nobody would write in reality such repeating blocks in the code and use functions instead.
Second note: After a stream is in error state, we need to clear that state and remove potential invalid characters from the input stream

Switch Case always goes to default

I am trying to make a small operating system that takes a response from a switch...case to go to a miniature game or a simple calculator. However, no matter what input I give (even correct ones) the output is always the default.
The compiler I am using (Microsoft Visual Studio; It could be the problem) isn't giving me any errors, and I can't find or think of any mistakes. Do some of you people who are actually good at this have any answers to my problem?
#include "stdafx.h"
#include <iostream>
#include <limits>
using namespace std;
int calc() {
char op;
float num1, num2;
cout << "Enter operation:";
cin >> op;
cout << "Enter two numbers:";
cin >> num1 >> num2;
switch (op)
{
case '+':
cout << num1 + num2;
break;
case '-':
cout << num1 - num2;
break;
case '*':
cout << num1 * num2;
break;
case '/':
cout << num1 / num2;
break;
default:
cout << "That is not an operation";
break;
}
return 0;
};
int main()
{
char answer;
cout << "Welcome to the FR Operating System. \n";
cout << "If you want to go to the calculator, type in 'Calc'. \n";
cout << "If you want to go to the game, type in 'Game'. \n";
cin >> answer;
switch (answer) {
case 'Calc' || 'calc':
cout << "Welcome to the calculator. \n";
break;
case 'Game':
cout << "Welcome to our game, 'A Day in the Life'. \n";
break;
default:
cout << "That is an invalid answer. This has caused the system to crash. \n";
break;
}
atexit([] { system("PAUSE"); });
return 0;
}
'Game' is not a valid string
Even if you replace it by "Game", which is a valid string, switch doesn't work with strings.
So either use single chars in your switch or use if-else blocks where you compare std::strings via ==.
std::string answer;
cin >> answer;
if (answer == "Calc" || answer == "calc")
//...
else if (answer == "Game")
//...
else
// invalid
Use map to item callbacks
Ideally, it would be better to map item menu to it's respective actions. std::map<std::string, std::function<void()>> allows exactly that! Read the inline comments to make sense of the rest:
#include <string>
#include <map>
#include <iostream>
#include <functional>
int main()
{
std::map<std::string, std::function<void()>> menu_items;
menu_items.emplace("calc", [](){std::cout << "calculate chosen\n";}); //use lambdas to spare boilerplate
menu_items.emplace("game", [](){std::cout << "game is chosen\n";});
std::string chosen_item;
std::cin >> chosen_item;
auto item = menu_items.find(chosen_item); //search by the string
if (item == menu_items.end()) //item was not found in the list
std::cout << "invalid item is chosen\n";
else
item->second(); //execute the stored function
}
Demo.
Depending on your usage you might want to use void*() for std::function<void()>, and std::unordered_map for std::map. For your usage case it doesn't seem to matter though.
Also you might want to normalize the input, e.g. lowercase the string, or perform some other normalization. Since this is not performance sensitive part of the code, I believe overhead of std::function and std::map won't matter in this case.
You are prompting user for a string while your variable answer is a char, change your prompts to characters like c and g thus make it more convenient, thus you can use and enumerate characters in your switch / case statement:
int main()
{
char answer;
cout << "Welcome to the FR Operating System. \n";
cout << "If you want to go to the calculator, type in 'c'. \n";
cout << "If you want to go to the game, type in 'g'. \n";
cin >> answer;
switch (answer) {
case 'c':
case 'C':
cout << "Welcome to the calculator. \n";
break;
case 'g':
case 'G':
cout << "Welcome to our game, 'A Day in the Life'. \n";
break;
...

Entering specific character into while loop

I am writing a code for class that asks the user to input a size that is an odd number equal to or greater than 7. I have been able to make that part of my code work successfully. However, the next part consists of asking the user to enter a specific letter, in this case 'c'. If they do not enter 'c' then the loop should ask them to input another character. Whenever I run this code, it is creating an infinite loop whether I enter 'c' or another letter. I think my expression in my second while loop is incorrect, but I haven't been able to find a lot of information regarding this that could help me.
#include <iostream>
using namespace std;
int main() {
int s, l;
cout << "Welcome to the letter printer." << endl;
cout << "Enter the size: " << endl;
cin >> s;
while (s < 7 || s%2==0 || s<0)
{
cout << "Invalid size. Enter the size again: " << endl;
cin >> s;
}
cout << "Enter the letter: " << endl;
cin >> l;
while (l != 'c')
{
cout << "Invalid letter. Enter the letter again: " << endl;
cin >> l;
}
return 0;
}
because you are getting char for int variable
wrong:
int s, l;
right one:
int s;
char l;
what is why it goes on infinite loop in second while
explanation for infinite loop
This is how basic_istream works. In your case when cin >> l gets
wrong input - failbit is set and cin is not cleared. So next time it
will be the same wrong input. To handle this correctly you can add
check for correct input and clear&ignore cin in case of wrong input.
incorporated from here

Programming Principles and Practice: chapter 4 drill part 1

I just can't seem to get this program to work properly. I can get it to accept two integers and print them to the screen. But I can't get the program to terminate when the '|' is used. Once that its entered it loops infinitely. Here is the code that I have so far:
#include "../../std_lib_facilities.h"
int main()
{
int num1 = 0;
int num2 = 0;
char counter = '\0';
cout << "Please enter two integers and press enter. \n";
bool test = true;
while (counter != '|')
{
cin >> num1 >> num2;
cout << "Your numbers are: " << num1 << " " << num2 << endl;
if (cin.fail())
{
cout << "Goodbye!\n";
test = false;
}
else (counter != '|');
cout << "Enter more numbers or press '|' to exit.\n";
}
system("pause");
}
You are using the wrong condition in your while loop. You are never changing counter so the loop will never end. However you do change test to false in the while loop if the input fails. You can change the condition of the while loop to use test instead like
while(test)
{
//...
}
Since counter is no longer being used you can get rid of it completely.
Please note that unless you change to taking in string and parsing the input any input that will cause cin to fail will end the loop not just a |.

Simple Reverse Polish Calculator

I am having trouble figuring out how to store the operator that the user inputs. I think my line 36 is what is causing my problem but not sure so what happens (I'm sure you can see from the code but I can't ;)) is I get to line 35 and put in the operation to use for the integers and hit enter nothing happens I then type in any 2 alphanumeric characters hit enter and nothing then 2 alphanumeric and enter then it spits out my answer. I know it's probably something so easy I am missing.
Also after I get that part working I would like to add a "do while" loop for the user to continue to use whichever operator that was choose until iValue1 !=0
Lastly, is the simplest way to prevent a user to divide by 0 using an "if" cin.fail? If so would that go with my first "if" statement?
*Edit: Line 35 = "cout << "Enter the operation you want to perform:"
#include <iostream>
using namespace std;
int main()
{
float iValue1, iValue2, iValue3;
char chOperator1 = '/'; //Initializing operators
char chOperator2 = '*';
char chOperator3 = '+';
char chOperator4 = '-';
//Get user inputs
cout << "Enter the first value as an integer: ";
cin >> iValue1;
cout << "Enter the Second value as an integer: ";
cin >> iValue2;
cout << "Enter the operation you want to perform: ";
cin >> chOperator1 >> chOperator2 >> chOperator3 >> chOperator4;
if( chOperator1 == '/')
{
iValue3 = iValue1 / iValue2;
}
else {
if(chOperator2 == '*')
iValue3 = iValue1 * iValue2;
(chOperator3 == '+');
iValue3 = iValue1 + iValue2;
(chOperator4 == '-');
iValue3 = iValue1 - iValue2;
}
cout << "The result is \n " << iValue3;
return 0;
}
I suggest you use an array or a std::vector for multiple operations:
char operations[4];
cout >> "Enter 4 operations: ";
for (unsigned int i = 0; i < 4; ++i)
{
cin >> operation[i];
}
for (unsigned int j = 0; j < 4; ++j)
{
const char opr = operation[j];
switch (j)
{
case '*':
cout << (iValue1 * iValue2) << "\n";
break;
case '/':
cout << (iValue1 / iValue2) << "\n";
break;
case '+':
cout << (iValue1 + iValue2) << "\n";
break;
case '-':
cout << (iValue1 - iValue2) << "\n";
break;
default:
cout << "Invalid operation, '" << oper << "'\n";
break;
}
}