gauge the rate of inflation for c++ - c++

Write a program to gauge the rate of inflation for the past year. The program asks for the price of an item (such as a hot dog or a 1-carat diamond) both one year ago and today. It estimates the inflation rate as the difference in price divided by the year-ago price. Your program should allow the user to repeat this calculation as often as the user wishes. Define a function to compute the rate of inflation. The inflation rate should be a value of type double giving the rate as a percent, for example 5.3 for 5.3 percent.
Your program must use a function to compute the rate of inflation. A program which does not use a function will be awarded a score of zero, even if all tests pass.
I want to repeat the loop, but no wonder I input Y or N, the loop will also repeat. Suppose the loop should repeat when I input 'Y' or 'y'. Can anyone tell me what's wrong with my code?
#include <iostream>
#include <cmath>
using namespace std;
double calculate_inflation(double, double);
int main()
{
double yearAgo_price;
double currentYear_price;
double inflation_Rate;
char again;
do{
cout << "Enter the item price one year ago (or zero to quit) : " << endl;
cin >> yearAgo_price;
cout << "Enter the item price today: " << endl;
cin >> currentYear_price;
cout.setf(ios::fixed)
cout.setf(iOS::showpoint);
cout.precision(2);
inflation_rate=calculate_inflation(yearAgo_price, currentYear_price);
cout << "The inflation rate is " << (inflation_rate*100) << " percent." << endl;
cout << "Do you want to continue (Y/N)?" << endl;
cin >> again;
}while((again =='Y') || (again =='y'));
return 0;
}
double calculate_inflation (double yearAgo_price, double currentYear_price)
{
return ((currentYear_price-yearAgo_price)/ yearAgo_price);
}

while((again='Y') || (again='y'));
should be
while((again=='Y') || (again=='y'));
You have mistaken assignment for comparison operator. Those are different in C and C++.
The effect of your code is that Y or y is assigned to again and the new value is returned. That char is non-zero so converts to true. Thus, true is returned, and the loop turns endless.
Edit:
How you could've found it out yourself with a debugger:
The loop appears to be endless thus we need to check its condition variable. So, place a watch on the again variable and see it change when the loop condition is being evaluated. Problem found.

while ((again='Y') || (again='y') does not do what you think it does. You are assigning to the again variable.
What you want to do is use the == operator to compare again to either 'Y' or 'y'.

Related

while loop doesn't loop in c++

So i just started C++ yesterday, I had a fair bit of java experience so that be the cause idk,
I try to run this code and for some reason the while loop isn't looping, i tried changing the if break statement from ask==false to ask=false, that just ends up with an infinite loop without even taking user input.
Here's the code:
#include <iostream>
#include <math.h>
using namespace std;
int main(){
double raduis;
const double pi = 3.14;
bool ask;
while(true){
cout << "Enter the raduis of the circle:"<< endl;
cin >> raduis;
double circ = 2*pi*raduis;
double area = pi*pow(raduis,2);
cout << "The Circumference of the circle is: "<< circ <<endl;
cout << "The Area of the circle is: "<< area<<endl;
cout <<"Would you like to run again?"<< endl;
cin >> ask;
if(ask==false){
break;
}
}
}
I've tried changing the bool to a char value with "y" or "n" values but to no avail nothing works.
Edit: Okay so I've solved the problem, as per #zdf 's suggestion I entered cin >> boolalpha >> ask; and it works perfectly now.
Call clear on cin before the input and make sure the input is only 0 or 1,
From cppreference:
If the type of v is bool and boolalpha is not set, then if the value to be stored is ​0​, false is stored, if the value to be stored is 1, true is stored, for any other value std::ios_base::failbit is assigned to err and true is stored.

Infinite loop created when inputting "yy" into a char variable that should only take a single character such as 'y' or 'n', "nn" does not break code

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.

writing a code for time to double annual interest rate

I'm trying to write a code for annual interest rate that lets you enter any amount, and it will show you approximately how many years it takes for your money to at least double. The given interest rate is 5% yearly. Thing is, it's not working properly and it's displaying absurdly high numbers, like 200 years or so.
#include <iostream>
using namespace std;
int main() {
int deposit;
int counter;
cout << "Deposit an amount NO LESS than 1000." << endl;
cin >> deposit;
for (deposit ;; deposit = 1.05 * deposit) {
counter = counter+1;
if (deposit >= 2 * deposit) {
cout << endl;
cout << "Your money will double in "<< counter <<" years." << endl;
break;
}
}
}
Instead of using a loop, you could calculate the time taken to double the money directly.
The amount of money is not interesting, so you don't need to store the amount of money. It's only the rate of return that's interesting.
You can calculate it directly as log(2) / log(r) where r is the rate of return. For example log(2) / log(1.05) gives you the exact time to double an initial amount of money with a 5% return.
Include the standard <cmath> header to get std::log().
#include <iostream>
#include <cmath>
int main() {
double yearsToDouble = std::log(2) / std::log(1.05);
std::cout << "Your money will double in "<< yearsToDouble << " years." << std::endl;
}
Use a variable to store the initial deposit so that it can be compared to the cumulative amount with interest.
for (float initdeposit = deposit;; deposit = 1.05 * deposit)
{
counter = counter+1;
if (deposit >= 2 * initdeposit)
{
cout << endl;
cout << "Your money will double in "<< counter <<" years." << endl;
break;
}
}
a.exe
Deposit an amount NO LESS than 1000.
1000
Your money will double in 16 years.
Note: No matter what the amount is, the time taken to double will be the same always. :)
if (deposit >= 2 * deposit) {
cout << endl;
cout << "Your money will double in "<< counter <<" years." << endl;
break;
}
In the above if statement you are expecting deposit to be greater than or equal to 2 times of deposit. Which can only be true in case if the value of deposit is zero or less than zero.
I will suggest you to use a temp variable to keep the input value of deposit and proceed.
To add to the other answers, which are largely correct in pointing out that deposit > 2*deposit can never be true (you need a second variable to record the initial value!), the only reason your loop ends at all is because deposit gets so large that 2*deposit "wraps around" due to overflow.
This appears to make 2*deposit bigger than deposit (logically impossible — you need to fix this comparison!) although strictly speaking the results are undefined.
Apparently this happens to you after 200 or so iterations.
As for suggestions to switch to a floating-point type like double, this is tempting, and may be sufficient in this simple case, but as a general rule you should avoid floating-point when you don't need it as it introduces complexities and inaccuracies for very little gain.
I would recommend counting in integer pennies, or tenths of pennies, instead. You can achieve it by multiplying the input by 100 or 1000. The resulting incremental multiplication by 1.05 will have a rounding factor, then, but this is what the banks will be doing too!
This line
if (deposit >= 2 * deposit) {
Will not evaluate to true (unless deposit is negative or barring someedge case). You probably wanted to compare it to an initial value. So after this:
cin >> deposit;
I would put
double initialDeposit = deposit;
And then change the other line to
if (deposit >= 2 * initialDeposit) {

C++ special-value-type loop has to exit when a negative value is entered without using break statement

I just completed a program that has to quit when a negative value is entered as input. Everything is working good except for only one issue, it quits the program after the second time a negative value is entered. After some research I noticed the use of break, however the samples I have to guide the assignment use only if and else statement.
#include <iostream>
using namespace std;
int main()
// insert code here...
// create a variable named "pounds" that can be used to store an integer.
// wait for the user to type in a value and put that value into the variable ounces
{
int poundsTotal;
int ouncesTotal;
while (poundsTotal >= 0)
{
cout << "Enter pounds or a negative number to quit: ";
cin >> poundsTotal;
ouncesTotal = poundsTotal * 16;
cout << poundsTotal << " pouds is " << ouncesTotal << " ounces." <<endl;
cout << " Enter pounds or a negative number to quit ";
cin >> poundsTotal;
poundsTotal++;
}
if (poundsTotal == 0){
cout <<"you enter a zero value" <<"Try onemore time";
}
else {
cout << "you chose to quit the program" <<poundsTotal;
}
}
The condition of a while loop is evaluated after the body has been executed. Then it is determined whether the body will be run again. Change your code and add an if statement inside the loop.
if(poundsTotal < 0) break;
And yes, a break statement is useful in a loop. Otherwise you can't stop the loop before your test condition is evaluated to false.
In your case, I find using a break would be a simple option.
When the program first reaches while (poundsTotal >= 0), poundsTotal has no defined value. This puts you at the mercy of the gods as to whether the program will work as expected or not, and Gods are notoriously unreliable. For more information, look up the term Undefined Behaviour.
The solution to this is ask the user for poundsTotal before the loop and once more at the end of the loop.
If you want to get really posh and do this without repeating code (and stay DRY) , make a function that gets poundsTotal from the user and call this function in the while loop's condition. For example,
while ((poundsTotal = getPoundsTotal()) >= 0)
{
...
}

C++ cin positive integers only

This is my first time on Stackoverflow.
I was making a program to find out MPG for a car. I was wondering how can I make the cin statement only accept positive integers only? and also, if you do enter a invalid input, can you reset it? I am not sure if that makes sense. I didn't have to do this for class. I was just curious on how to do it. Here is the code.
#include <iostream>
using namespace std;
int main()
{
double tank, miles, mpg;
cout << "Hello. This is a program that calculates the MPG ( Miles Per Gallon) for your\n" ;
cout << "vehicle\n" << endl;
cout << "Please enter how many gallons your vehicle can hold\n" << endl;
cin >> tank;
cout << endl;
cout << "Please enter how many miles that have been driven on a full tank\n" <<endl;
cin >> miles;
cout << endl;
mpg = (miles)/(tank);
cout << "Your vehicle recieves " << mpg << " miles per gallon\n" << endl;
system ("pause");
return 0;
}
iostreams are not a toolkit for building a complex UI. Unless you want to write your own rather complex stream to wrap the usual stream, there is no way you are going to get it to either (a) only accept positive integers or (b) interact politely with a user who types in something else.
You should just read lines from cin, and print your own error prompts and such after you look at what you get.
cout << "Hello. This is a program that calculates the MPG ( Miles Per Gallon) for your\n" ;
cout << "vehicle\n" << endl;
do
{
cout << "Please enter how many gallons your vehicle can hold\n" << endl;
cin >> tank;
cout << endl;
} while (tank <= 0 && ((int)tank != tank));
do
{
cout << "Please enter how many miles that have been driven on a full tank\n" <<endl;
cin >> miles;
cout << endl;
} while (miles <= 0 && ((int)miles != miles));
If you do this after running the statements it will rerun them if the answer is 0 or lower or is not an integer. If you make the variables ints instead of doubles then you can remove the "&& ((int)miles == miles)" part of the while statement.
Still, there are a couple of standard ways to do it in a command line environment.
You could trap the cin statement in a loop that doesn't release until a valid input has been entered. This is the "standard" way to validate CLI input, not just signed numbers.
do
{
cout << "\nPlease enter...";
cin >> tank;
}
while (tank < 0)
The condition in the while statement is the place to validate the data. You can also make an if statement to explain why the input is invalid.
The other way is to simply force the value to be positive, by simply going tank = fabs(tank);, which takes the absolute value (i.e. positive) of the tank variable.
So this is my code for an infinite loop
1: So main will call the "Get_number()" function
2: Get number will accept an int from the user
3(A): If int is greater than 0, go into loop
3(B): Else, display to user "Invalid Input" and then call the function
"Get_number()" again creating an infinite loop until the user
enters a value greater than 0
#include <iostream> // Access the input output stream library
#include <fstream> // Access to the fstream library (used to read and write to files)
#include <chrono> // Needed to access "std::chrono_literals"
#include <thread> // Needed to access "namespace std::this_thread"
using std::fstream; // this will allow us to use the fstream (we'll be able to read and write to files)
using std::ios; // needed for iostream (used to be able to tell fstream to read and/or write to a file and that it's reading/writing a binary file)
using std::cout; // need this statment to access cout (to display info to user)
using std::cin; // need this statment to access cin (to gather info from user)
using std::endl; // need this statment to access endl (will end the line)
using namespace std::this_thread; // This will allow me to use "Sleep_For" or "Sleep_Until"
using namespace std::chrono_literals; // This will allow the use of measurements of time such as ns, us, s, h, etc.
//Prototypes***************************************************************************************************
void shellSort(int read[], int readLength); //Making Prototype (Declaring our function) so that compiler knows not to worry about it
void Get_number();
void Write_to_file(int user_input_of_how_many_random_numbers_to_generate); //Making Prototype (Declaring our function) so that compiler knows not to worry about it
void Read_from_file(int user_input_of_how_many_random_numbers_to_generate);//Making Prototype (Declaring our function) so that compiler knows not to worry about it
//*************************************************************************************************************
void main()
{
Get_number();
system("pause>>void"); // will let the console pause untill user presses any button to continue
}
/**************************************************************************************************************
* Purpose: This function will gather a positive integer from the user and use it to generate that many
* random numbers!
*
* Precondition: None
*
*
* Postcondition:
* Would've gathered the number of random numbers the user wanted to generate and then gone into the
* Write_to_file and Read_from_file function
*
**************************************************************************************************************/
void Get_number()
{
int user_input_of_how_many_random_numbers_to_generate = 0; //make variable that will accept the int value the user wants to generate random numbers
cout << "Please Enter A Number Greater Than Zero:" << endl; // displays to user to enter a number greater than zero
cin >> user_input_of_how_many_random_numbers_to_generate; // will accept the value the user inputted and place it in the "user_input_of_how_many_random_numbers_to_generate" variable
system("cls"); // Will clear the screen
if (user_input_of_how_many_random_numbers_to_generate > 0) // if user input is greater than zero, enter this
{
Write_to_file(user_input_of_how_many_random_numbers_to_generate); // will bring up the "Write_to_file" function
Read_from_file(user_input_of_how_many_random_numbers_to_generate); // will bring up the "Read_from_file" function
}
else // else enter this
{
cout << "invalid input!" << endl; // display to user "invalid input"
sleep_for(2s); // system will pause for 2 seconds allowing the user to read the message of "invalid input"
system("cls"); // console will be cleared
Get_number(); // Get_number function will be entered creating an infinate loop untill the user's input is valid!
}
}
Instead of
cin >> miles;
Try
while ( (cin >> miles) < 0 )
cout << "Please enter how many gallons your vehicle can hold\n" << endl;
That will repeat the question until the input is positive. You can do that for the rest of the questions too.
Note that input streams are not intended for input filtering. You have to provide your own logic for that.