I'm very new to C++. I started teaching myself C++ last week, and up until now, I haven't had any real problems.
I use Microsoft Visual Studio 2017, and I'm having problems with if and else statements. You see, I'm making this very limited calculator. Basically, the program gives you the 4 basic mathematical operations, and you choose which operation you want to use to calculate by entering either 1, 2, 3, or 4. Then, it runs another program which you can then calculate. (e.g.: 2 is for subtraction, if you enter 2, it will run the subtraction calculator)
Here's the code for the program.
#include "stdafx.h"
#include "iostream"
using namespace std;
int main(){
int add = 1;
int sub = 2;
int mul = 3;
int div = 4;
cout << "Extremely Limited C++ Calculator: Enter a number between one and
four to start calculating and press enter."
<< '\n'
<< "LEGEND"
<< '\n' << "1 = Addition"
<< '\n' << "2 = Subtraction"
<< "\n" << "3 = Multiplication"
<< '\n' << "4 = Division"
<< '\n' << "Operation: ";
if (cin >> add) {
system("start C:\\CalculatorApps\\addition.exe");
return 0;
}
if (cin >> sub) {
system("start C:\\CalculatorApps\\subtraction.exe");
return 0;
}
if (cin >> mul) {
system("start C:\\CalculatorApps\\multiplication.exe");
return 0;
}
if (cin >> div) {
system("start C:\\CalculatorApps\\division.exe");
return 0;
}
}
So I have the addition.exe and subtraction.exe done, but the problem is that no matter what number I enter, it will always run addition.exe. In the subtraction calculator, I experimented having the user choose if they wanted to subtract more than 2 numbers, but that also didn't end up working because it was ignoring if statements. I also at one point had an else statement on both the subtraction calculator and the main program that takes you to the calculators that displayed text reading that the number they entered was not a valid choice and to enter a valid choice, but even that was ignored by the program. Now, maybe I didn't look hard enough on the internet, but I couldn't find one that helped me out. If you know the answer, please tell me but in words that I can understand (I am new after all), or please link me to another question that has been answered that will solve my question.
Thank you in advanced!
cin is an object of class istream that represents the standard input stream. It corresponds to the cstdio stream stdin. The operator >>overload for streams return a reference to the same stream. The stream itself can be evaluated in a boolean condition to true or false through a conversion operator.
cin provides formatted stream extraction. The operation cin >> x;
where "x" is an int will fail if a non-numeric value is entered. So:
if(cin>>x)
will return false if you enter a letter rather than a digit.
As you are always entering a digit, your first statement if(cin>>sum) is always true. So, your other statements are skipped.
Related
The code in the cont function asks the user if they want to play my game again.
The code works when receiving proper character inputs such as 'y' or 'n' as well as their respective capital letter variants, and the else block works properly to loop the function if an invalid input such as 'a' or 'c' is entered.
However during a test run, an input of 'yy' breaks the code causing the program to infinitely loop, running not only this cont function but my game function as well.
choice is stored as a char variable. I am wondering why the code even continues to run upon inputting multi-character inputs such as 'yy' or 'yes'. What's interesting is 'nn', 'ny' and other variations of multi-character inputs that begin with 'n' causes no issues and properly results in the else if block running as intended. Which prints "Thanks for playing." then ends the program.
Can variables declared as char accept inputs greater than 1 character? Does it only take the first value? And if so why does 'yy' cause a loop rather than the program running as intended by accepting a value of 'y' or 'Y'? How can I change my program so that an input of 'yy' no longer causes issues, without specific lines targeting inputs such as 'yy' or 'yes'.
#include <iostream>
#include <string> // needed to use strings
#include <cstdlib> // needed to use random numbers
#include <ctime>
using namespace std;
// declaring functions
void cont();
void game();
void diceRoll();
// variable declaration
string playerName;
int balance; // stores player's balance
int bettingAmount; // amount being bet, input by player
int guess; // users input for guess
int dice; // stores the random number
char choice;
// main functions
int main()
{
srand(time(0)); // seeds the random number, generates random number
cout << "\n\t\t-=-=-= Dice Roll Game =-=-=-\n";
cout << "\n\nWhat's your name?\n";
getline(cin, playerName);
cout << "\nEnter your starting balance to play with : $";
cin >> balance;
game();
cont();
}
// function declaration
void cont()
{
cin >> choice;
if(choice == 'Y' || choice == 'y')
{
cout << "\n\n";
game();
}
else if (choice == 'N' || choice == 'n')
{
cout << "\n\nThanks for playing.";
}
else
{
cout << "\n\nInvalid input, please type 'y' or 'n'";
cont(); // calls itself (recursive function!!!)
}
}
void game()
{
do
{
cout << "\nYour current balance is $ " << balance << "\n";
cout << "Hey, " << playerName << ", enter amount to bet : $";
cin >> bettingAmount;
if(bettingAmount > balance)
cout << "\nBetting balance can't be more than current balance!\n" << "\nRe-enter bet\n";
} while(bettingAmount > balance);
// Get player's numbers
do
{
cout << "\nA dice will be rolled, guess the side facing up, any number between 1 and 6 : \n";
cin >> guess;
if(guess <= 0 || guess > 6 )
{
cout << "\nYour guess should be between 1 and 6\n" << "Re-enter guess:\n";
}
} while(guess <= 0 || guess > 6);
dice = rand() % 6+1;
diceRoll();
if (dice == guess)
{
cout << "\n\nYou guessed correctly! You won $" << (bettingAmount * 6);
balance = balance + (bettingAmount * 6);
}
else
{
cout << "\n\nYou guessed wrong. You lost $" << bettingAmount << "\n";
balance = balance - bettingAmount;
}
cout << "\n" << playerName << ", you now have a balance of $" << balance << "\n";
if (balance == 0)
{
cout << "You're out of money, game over";
}
cout << "\nDo you want to play again? type y or n : \n";
cont();
}
void diceRoll()
{
cout << "The winning number is " << dice << "\n";
}
Does it only take the first value?
Yes, the >> formatted extraction operator, when called for a single char value, will read the first non-whitespace character, and stop. Everything after it remains unread.
why does 'yy' cause a loop
Because the first "y" gets read, for the reasons explained above. The second "y" remains unread.
This is a very common mistake and a misconception about what >> does. It does not read an entire line of typed input. It only reads a single value after skipping any whitespace that precedes it.
Your program stops until an entire line of input gets typed, followed by Enter, but that's not what >> reads. It only reads what it's asked to read, and everything else that gets typed in remains unread.
So the program continues to execute, until it reaches this part:
cin >> bettingAmount;
At this point the next unread character in the input is y. The >> formatted extraction operator, for an int value like this bettingAmount, requires numerical input (following optional whitespace). But the next character is not numerical. It's the character y.
This results in the formatted >> extraction operator failing. Nothing gets read into bettingAmount. It remains completely unaltered by the >> operator. Because it is declared in global scope it was zero-initialized. So it remains 0.
In addition to the >> extraction operator failing, as part of it failing it sets the input stream to a failed state. When an input stream is in a failed state all subsequent input operation automatically fail without doing anything. And that's why your program ends up in an infinite loop.
Although there is a way to clear the input stream from its failed state this is a clumsy approach. The clean solution is to fix the code that reads input.
If your intent is to stop the program and enter something followed by Enter then that's what std::getline is for. The shown program uses it to read some of its initial input.
The path of least resistance is to simply use std::getline to read all input. Instead of using >> to read a single character use std::getline to read the next line of typed in input, into a std::string, then check the the string's first character and see what it is. Problem solved.
cin >> bettingAmount;
And you want to do the same thing here. Otherwise you'll just run into the same problem: mistyped input will result in a failed input operation, and a major headache.
Why do you need this headache? Just use std::getline to read text into a std::string, construct a std::istringstream from it, then use >> on the std::istringstream, and check its return value to determine whether it failed, or not. That's a simple way to check for invalid input, and if something other than numeric input was typed in here, you have complete freedom on how to handle bad typed in input.
Now, before this question gets marked for duplicate. I have already gone through most of the questions and their relative answers of C++. These are the links that I have tried and none of them work for me. It maybe because they are using an older version of C++, and I have the latest version of C++. Here are the links that I have tried:
Detecting ENTER key in C++
https://www.sololearn.com/Discuss/1863352/how-can-i-check-that-user-press-enter-key-in-c
http://www.cplusplus.com/forum/beginner/2624/
https://www.dreamincode.net/forums/topic/398680-detect-enter-key/
Now, with the duplicates out of the way. I am making an expression calculator. So, for example if the user input is: 2+2*6*9/9, then the output should be 14.
The code where I suspect that the problem lies is in:
#include <iostream>
#include <vector>
using std::cout;
using std::cin;
using std::string;
using std::vector;
void clear();
void error(string message);
int main() {
cout << "Enter an expression: ";
double l_Value = 0, r_Value = 0, result = 0, count = 0, previous_number;
char op;
while (cin >> l_Value) { // 1+2*3+6-4/2+3
if (!cin) {
error("Invalid operand entered!");
}
else {
bool is_Error = 0; // false
vector<double> numbers;
numbers.push_back(l_Value);
previous_number = l_Value;
while (cin >> op) {
if (op == '\0') {
break;
}
cin >> r_Value;
switch (op)
{
case '+':
numbers.push_back(r_Value);
previous_number = r_Value;
break;
case '-':
numbers.push_back((-1 * r_Value));
previous_number = (-1 * r_Value);
break;
case '*':
numbers.pop_back(); // take out the number
r_Value *= previous_number;
numbers.push_back(r_Value);
previous_number = r_Value;
break;
case '/':
if (r_Value == 0) {
error("Sorry, division by zero has occured. Please re-evaluate your expression!\n");
is_Error = 1; // true
break;
}
else {
numbers.pop_back(); // take out the number
previous_number /= r_Value;
numbers.push_back(previous_number);
break;
}
}
}
if (!is_Error) {
for (int i = 0; i < numbers.size(); i++) {
result += numbers[i];
}
cout << result << '\n';
}
numbers.clear();
result = 0;
l_Value = 0;
r_Value = 0;
}
cout << "Enter an expression: ";
}
clear();
return 0;
}
None of the links above seemed to work for me.
When I press the Enter key, it expects me to give another input, and that is not supposed to happen. So when I used cin.get() == 'n' or cin.get() == (int)'\n', it expects for another input. But, when I have an 'x' at the end of the expression, it works perfectly fine. So, I need the "cin" operator to help me detect an Enter character at the end of the expression and then terminate the program.
Here, is a sample run of a program with 'x':
[![running as x-terminator][1]][1]
[1]: https://i.stack.imgur.com/ORPQa.png
When I try the above solution such as "cin.get() == '\n':
Then, I thought that maybe it is reading the null character and so, I tried if (op == '\0'):
For the enter key and null character I had to press Ctrl+Z to terminate the program. Please help!
As, mentioned by user #idclev, I already have a string program that works, but I am trying to avoid using string to calculate any expressions! So, if I could detect an enter key pressed using a character datatype that would be great!
I avoided strings to avoid parsing through the text
That argument is moot. What you can read from cin you can also read from a std::string, no difference whatsoever. You just need to add one step:
#include <iostream>
#include <string>
#include <sstream>
int main( ){
std::string x;
std::cin >> x;
if (x == "") {
std::cout << "user pressed enter (and nothing else)";
} else {
double y;
std::stringstream ss{x};
ss >> y;
std::cout << y;
}
}
This will read one std::string. If user only hit enter then the string will be empty. If the user entered something the else branch will be taken and you can extract the number from the string in the same way you did extract the number from cin (via using a std::stringstream).
If you have more than one number in the input you need to use getline to read the string, because cin will (by default) only read till the next whitespace.
Again...
If I used a string, I would have a tough time in extracting single-digit and two-digit or n-number of digits in a string. The double data type does that for me
You can read single-digit or any number of digits from a stringstream in exactly the same way as you read them from cin.
I already made a program with string in it. I was trying to avoid string to see how much faster would it be without string.
It won't be any faster. Constructing the string and the stringstream is maybe in the order of microseconds. A user entering input is in the order of seconds, maybe milliseconds when they are typing very fast.
Your approach cannot work because hitting enter is not considered as a character. Trying to read a character when there is none in the stream will fail. It will not set the character to \n or \r.
On the outer loop, you are trying to read a double, but you keep pressing enter. There is no input to evaluate, so it keeps trying to read a double. You can get out of it by ending the input stream with ^Z, or you can give it any actual content to read, and it will try to make it into a double (which is what your code explicitly told it to wait for).
Basically, when you press enter, it's ignoring it because
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
Extracts as many characters as possible from the stream and inserts them into the output sequence controlled by the stream buffer object pointed by sb (if any), until either the input sequence is exhausted or the function fails to insert into the object pointed by sb.
Try experimenting with this to see what is happening.
#include <iostream>
#include <vector>
#include <string>
int main() {
double x;
std::cin >> x;
std::cout << "read this value: " << x << std::endl;
// this is what while or if will look at
bool success = !std::cin.fail();
if (success)
std::cout << "success" << std::endl;
else
std::cout << "failure, loop will exit" << std::endl;
return 0;
}
What you should want (in my opinion) is a function that takes the expression as a string, and returns the result, so you can write unit tests, and make sure the function works. You can use this function with any expression that you can put in a string. It doesn't HAVE to be typed in by a user.
If you want the user to type in the experession, it's a lot easier to just use getline() then pass the string to your function. The big problem with using cin on each variable and character is that the user has no idea which datetype is expected right then. Granted, it's not hard to guess with an expression, but you wrote it and debugged it and still didn't know which cin you were failing to get the right datatype to. (this is normal, btw -- been there, which is why I getline and parse separately)
I'm new to C++. I stumbled upon one tutorial problem, and I thought I'd use the few things I have learnt to solve it. I have written the code to an extent but the code exits at a point, and I really can't figure out why. I do not want to go into details about the tutorial question because I actually wish to continue with it based on how I understood it from the start, and I know prospective answerers might want to change that. The code is explanatory, I have just written few lines.
Here comes the code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
double average_each_student() {
cout << "\n>Enter your scores seperated by spaces and terminated with a period\n"
<< ">Note: scores after total number of six will be truncated.\n"
<< endl;
double sum = 0, average = 0;
int user_input, counter = 0;
const double no_of_exams = 6;
while(cin >> user_input) {
++counter;
if(counter < 5) sum += 0.15 * user_input;
else if(counter > 4 && counter < 7) sum += 0.20 * user_input;
}
return sum / no_of_exams;
}
int reg_number() {
cout << "Enter your registration number: " << endl;
int reg_numb;
cin >> reg_numb;
return reg_numb;
}
int main() {
vector<int> reg_num_list;
vector<double> student_average;
reg_num_list.push_back(reg_number());
student_average.push_back(average_each_student());
string answer;
cout << "\n\nIs that all??" << endl;
//everything ends at this point.
//process returns 0
cin >> answer;
cout << answer;
}
The code exits at cout << "\n\nIs that all??" << endl;. The rest part after that is not what I intend doing, but I'm just using that part to understand what's happening around there.
PS: I know there are other ways to improve the whole thing, but I'm writing the code based on my present knowledge and I wish to maintain the idea I'm currently implementing. I would appreciate if that doesn't change for now. I only need to know what I'm not doing right that is making the code end at that point.
The loop inside average_each_student() runs until further input for data fails and std::cin gets into failure state (i.e., it gets std::ios_base::failbit set).
As a result, input in main() immediately fails and the output of what was input just prints the unchanged string. That is, your perception of the program existing prior to the input is actually wrong: it just doesn't wait for input on a stream in fail state. Since your output doesn't add anything recognizable the output appears to do nothing although it actually prints an empty string. You can easily verify this claim by adding something, e.g.
std::cout << "read '" << answer << "'\n";
Whether it is possible to recover from the fail state on the input stream depends on how it failed. If you enter number until you indicate stream termination (using Ctrl-D or Ctrl-Z on the terminal depending on what kind of system you are using), there isn't any way to recover. If you terminate the input entering a non-number, you can use
std::cin.clear();
To clear the stream's failure stated. You might want to ignore entered characters using
std::cin.ignore(); // ignore the next character
or
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// ignore everything up to the end of the line
use cin.clear(); before cin >> answer; That will fix the problem. But you are not controlling the input. it just runs out to cin..
/**
Write a program that reads a series of numbers and stores them in a vector. After the user inputs all the numbers he or she wishes to, ask how many of the numbers the user wants to sum. For an answer N. print the sum of the first N elements of the vector. For example: "Please enter some numbers (press 'I' at prompt to stop ) : " 12 23 13 24 15 "Please enter how many of the numbers you wish to sum, starting from the first:" 3 "The sum of the first 3 numbers : 12, 23, and 13 is 48." Handle all inputs. For exam ple, make sure to give an error message if the user asks for a sum of more numbers than there are in the vector.
**/
#include<iostream>
#include<vector>
using namespace std;
int main()
{
try
{
vector<int> numbers;
int num;
cout<<"Now enter the numbers";
while(cin>>num)
numbers.push_back(num);
int n,sum=0;
cout << "Enter the nth number to find sum of elements till n : ";
cin>>n;
if(n >numbers.size())
throw 66;
for(int i=0;i<n;i++)
sum+=numbers[i];
cout << "sum is "<<sum;
return 0;
}
catch(int k)
{
cerr<<"Error "<<k;
return -1;
}
}
So , when I enter EOF , CTRL+D , the program terminates. I am not sure where it is going wrong. I even tried to debug using gdb(with the help from an online tutorial) . It didn't just work out . can someone tell me what's wrong with the code ?
You are not checking if you actually read anything.
Consider this little test program:
#include <iostream>
int main()
{
std::cout << "std::cin is " << (std::cin ? "ready" : "done") << "\n";
int n = -42;
std::cin >> n;
std::cout << n << "\n";
std::cout << "std::cin is " << (std::cin ? "ready" : "done") << "\n";
n = -42;
std::cin >> n;
std::cout << n << "\n";
std::cout << "std::cin is " << (std::cin ? "ready" : "done") << "\n";
}
The output, when fed with an empty standard input (which is equivalent to immediately declaring its end with ctrl+d) is:
std::cin is ready
-42
std::cin is done
-42
std::cin is done
As you can see, n is never changed, as there is never a new value to change it to! Also, you can easily spot that the state of std::cin reflects if the previous read went past the end.
Since you are only checking the value of your integers without ensuring that they have a sane default (just check what happens to n if it is not set by reading the input), this can easily lead to your program exhibiting unexpected behavior.
Note: The behavior of the test program is different when fed input that simply is not a number.
When you supply cin with EOF it causes cin.failbit to become true. With the failbit set to true, all subsequent cin reads will be ignored. Since n has no default value execution becomes unpredictable from here. In my case the program was crashing because it was throwing 66. Adding cin.clear() after the while loop will fix this, but is not advisable. Two simple solutions would to stop on a magic number/prompt the user after every input if they want to continue.
Title probably sounds confusing so first I'll show you my code, I made this simple program to get two input values and multiply them, and another thing, but that's not important, It works correctly:
#include <iostream>
using namespace std;
main()
{
int a,b,c,d,e;
char j = 4;
cout << "Welcome to Momentum Calculator\n\n";
cout << "------------------------------\n";
cout << "Please Enter Mass in KG (if the mass in in grams, put \"9999\" and hit enter): \n\n";
cin >> a;
if (a==9999) {
cout << "\nPlease Enter Mass in grams: \n\n";
cin >> d;
}
else {
d = 0;
}
cout << "\nPlease Enter Velocity \n\n";
cin >> e;
if (d == 0)
{
c = (a*e);
}
else {
c = (e*d)/100;
}
cout << "\nMomentum = " << c;
cin.get();
cin.ignore();
while (j == 4)
{
cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
main();
}
}
Now as you can see, my variable is an int (integer) and my problem is If I enter an English letter (a-z) or anything that is not a number will cause it to repeat my program unlimited times at an unlimited speed. I want a string/char to see if my var "a" is a letter or anything but don't know how to. I can do it, however, I want user to input only one time in "a" and mine makes him to enter again. Please Help :)
There is a function called isalpha in ctype library, checks whether your variable is an alphabetic letter so you can do using isalpha function.
Will isdigit or isalpha from standard library help you?
P.S.
1KG contains 1000 grams, so you should divide by 1000, not by 100;
UPDATE:
Seems I understood your question...
You need cin.clear(); before cin.get() and cin.ignore().
Otherwise the these calls won't do anything, as cin is in an error state.
I think you can get a as an String, and see if it contains English letter or not, if it contains, again ask for the input ( you can do it in a while loop ). And when a correct input entered, parse it and find what is it's number.