if statements for c++ - c++

My program so far, my question is do i have to include the if statements after each cout/cin code or is there a way to generalize it? :
#include <iostream>
using namespace std;
int main ()
{
double watts, hours_per_day, watt_hours, dollars_per_wh, result;
dollars_per_wh= .00008;
cout << " How many Watts for the Air conditioner? ";
cin >> watts;
cout << " How many hours/day do you run the Air Conditioner? ";
cin >> hours_per_day;
if (watts< 0)
{
cout << "Error- negative watts detected " << endl;
return 1;
}
if (hours_per_day< 0)
{
cout << "Error - negative hours/day detected " << endl;
return 1;
}
cout << "How many Watts for the Television? " ;
cin >> watts;
cout << "How many hours/day do you run the Television? " ;
cin >> hours_per_day;
if (watts< 0)
{
cout << "Error- negative watts detected " << endl;
return 1;
}
if (hours_per_day< 0)
{
cout << "Error - negative hours/day detected " << endl;
return 1;
}
cout << "How many Watts for the Washer? " ;
cin >> watts;
cout << "How many hours/day do you run the Washer? " ;
cin >> hours_per_day;
if (watts< 0)
{
cout << "Error- negative watts detected " << endl;
return 1;
}
if (hours_per_day< 0)
{
cout << "Error - negative hours/day detected " << endl;
return 1;
}
return 0 ;
}

You can write a function that takes two parameters:
bool check(int watts, int hours_per_day)
{
if (watts< 0)
{
cout << "Error- negative watts detected " << endl;
return false;
}
if (hours_per_day< 0)
{
cout << "Error - negative hours/day detected " << endl;
return false;
}
}
Then in your main function you can replace the two if statements with one:
if(!check(watts, hours_per_day))
{
return 1;
}
If you want to collect all the inputs first and then evaluate them, then maybe use an array for watts and hours_per_day. Then you can run through the array and check each entry.

Yes, you can pull them out into a separate function:
void cinNonNegative(double &x)
{
cin >> x;
if (x< 0)
{
cout << "Error- negative value detected " << endl;
exit(1);
}
}
int main()
{
...
cout << " How many Watts for the Air conditioner? ";
cinNonNegative(watts);
cout << " How many hours/day do you run the Air Conditioner? ";
cinNonNegative(hours_per_day);
...
}
And if you want to be more specific about the error message (e.g. "negative watts" instead of "negative value") you can add another parameter to cinNonNegative for the name of the variable (e.g. "watts").

The following solution gives you a function that:
Returns a boolean that says if the function succeeded/failed
Allows you to name the value that should be received
Allows you to set minimal and maximal values
If needed, you can build other custom functions for getting integers, or other functions for getting any other kind of input. This way you can concentrate all the input tests into a single place.
#include <iostream>
using namespace std;
bool getint(int &result, const char *name, int minValue, int maxValue)
{
bool success = false;
int value = 0;
cout << "Please enter " << name << ": ";
if (!(cin >> value))
{
cout << "Error: bad input detected" << endl;
}
else if (value < minValue)
{
cout << "Error: " << name << " is less than " << minValue << endl;
}
else if (value > maxValue)
{
cout << "Error: " << name << " is more than " << maxValue << endl;
}
else
{
success = true;
result = value;
}
return success;
}
int main()
{
int watts;
getint(watts, "Watts for the AC", 0, 10000);
return 0;
}

Related

guessing game while loop not looping

#include <iostream>
using namespace std;
bool play_game(int n) {
int guess;
bool noguesses = false;
int numofguesses = 0;
cout << "Welcome to my number guessing game\n";
while (n!=guess && !noguesses)
{
if (numofguesses < 6)
{
cout << "\n";
cout << "Enter your guess: ";
cin >> guess;
cout << "\n";
cout << "You entered: " << guess;
numofguesses++;
return false;
}
else
{
oog = true;
}
}
if (noguesses) {
cout << "I'm sorry. You didn't find my number.\n";
cout << "It was" << n << endl;
}
else
{
cout << "\n";
cout << "You found it in" << numofguesses << "guess(es)\n";
return true;
}
}
int main()
{
int secretnum = 5;
play_game(secretnum);
}
When I run this, the program stops after cout << "You entered: " << guess;. I want it to keep looping until the number of guesses reaches 6, or until the user inputs the correct answer.
Remove return false;
if (numofguesses < 6)
{
cout << "\n";
cout << "Enter your guess: ";
cin >> guess;
cout << "\n";
cout << "You entered: " << guess;
numofguesses++;
return false; //Remove this line
}

memory leaks in c++

#pragma once
#ifndef SDDS_GIFT_H
#define SDDS_GIFT_H
#include <iostream>
namespace sdds
{
const int MAX_DESC = 15;
const double MAX_PRICE = 999.999;
const int MAX_WRAP = 20;
struct Gift
{
char m_description[MAX_DESC];
double m_price;
int m_units;
int m_wrapLayers;
struct Wrapping* m_wrap;
};
struct Wrapping
{
char* m_pattern;
};
void gifting(char*);
void gifting(double&);
void gifting(int&);
bool wrap(Gift& theGift);
bool unwrap(Gift& theGift);
void gifting(Gift& theGift);
void display(const Gift& theGift);
}
#endif
<pre><code>
#include <iostream>
#include "Gift.h"
using namespace std;
namespace sdds
{
void gifting(char* m_description) // sending info
{
cout << "Enter gift description: ";
cin.width(MAX_DESC + 1);
cin >> m_description;
}
void gifting(double& m_price)
{
cout << "Enter gift price: ";
cin >> m_price;
while (m_price > MAX_PRICE || m_price < 0)
{
cout << "Gift price must be between 0 and " << MAX_PRICE << std::endl;
cout << "Enter gift price: ";
cin >> m_price;
}
}
void gifting(int& m_units)// gifting function
{
cout << "Enter gift units: ";
cin >> m_units;
while (m_units < 1)
{
cout << "Gift units must be at least 1" << std::endl;
cout << "Enter gift units: ";
cin >> m_units;
};
}
bool wrap(Gift& m_wrap) {
if (m_wrap.m_wrapLayers > 0) {
cout << "Gift is already wrapped!" << endl;
return false;
}
else {
cout << "Wrapping gifts..." << endl;
cout << "Enter the number of wrapping layers for the Gift: ";
cin >> m_wrap.m_wrapLayers;
while (m_wrap.m_wrapLayers < 1) {
cout << "Layers at minimum must be 1, try again." << endl;
cout << "Enter the number of wrapping layers for the Gift: ";
cin >> m_wrap.m_wrapLayers;
}
int i = 0;
m_wrap.m_wrap = new Wrapping[MAX_WRAP + 1];
for (i = 0; i < m_wrap.m_wrapLayers; i++) {
m_wrap.m_wrap->m_pattern = new char[MAX_WRAP + 1];
cout << "Enter wrapping pattern #" << i + 1 << ": ";
cin >> m_wrap.m_wrap->m_pattern;
} // I put struct in a structure
return true;
}
delete[]m_wrap.m_wrap;
m_wrap.m_wrap = nullptr;
}
bool unwrap(Gift& g_unwrap) // unwrap function
{
if (g_unwrap.m_wrapLayers > 0) {
cout << "Gift being unwrapped." << endl;
g_unwrap.m_wrapLayers = 0;
g_unwrap.m_wrap->m_pattern = nullptr;
return true;
}
else
{
cout << "Gift isn't wrapped! Can't unwrap." << endl;
return false;
}
}
void display(const Gift& theGift)
{
cout << "Gift Details:" << endl;
cout << " Description: " << theGift.m_description << endl;
cout << " Price: " << theGift.m_price << endl;
cout << " Units: " << theGift.m_units << endl;
if (theGift.m_wrap == nullptr) // this part seems like a problem
{
cout << "Unwrapped" << endl;
}
else
{
int i = 0;
cout << "Wrap Layers: " << theGift.m_wrapLayers << endl;
for (i = 0; i < theGift.m_wrapLayers; i++) {
cout << "Wrap #" << i + 1 << ": " << theGift.m_wrap[i].m_pattern << endl;
}
}
}
void gifting(Gift& gift) //last function
{
cout << "Preparing a gift..." << endl;
gifting(gift.m_description);
gifting(gift.m_price);
gifting(gift.m_units);
wrap(gift);
}
}
</code></pre>
/***********************************************************************
// Workshop 2: Dynamic Memory & Function Overloading
// Version 2.0
// Date 2020/05/05
// Author Michael Huang
// Description
// Tests Gift module and provides a set of TODOs to complete
// which the main focuses are dynamic memory allocation
//
/////////////////////////////////////////////////////////////////
***********************************************************************/
#include <iostream>
#include "Gift.h"
#include "Gift.h" // intentional
using namespace std;
using namespace sdds;
void printHeader(const char* title)
{
char oldFill = cout.fill('-');
cout.width(40);
cout << "" << endl;
cout << "|> " << title << endl;
cout.fill('-');
cout.width(40);
cout << "" << endl;
cout.fill(oldFill);
}
<pre><code>
int main() {
Gift g1; // Unwrapped Gift
{
printHeader("T1: Checking Constants");
cout << "MAX_DESC: " << sdds::MAX_DESC << endl;
cout << "MAX_PRICE: " << sdds::MAX_PRICE << endl;
cout << "MAX_WRAP: " << sdds::MAX_WRAP << endl;
cout << endl;
}
{
printHeader("T2: Display Wrapped Gift");
gifting(g1.m_description);
gifting(g1.m_price);
gifting(g1.m_units);
cout << endl;
g1.m_wrap = nullptr;
g1.m_wrapLayers = 0;
display(g1);
cout << endl;
}
{
printHeader("T3: Wrap a gift");
if (wrap(g1))
cout << "Test succeeded!";
else
cout << "Test failed: wrapping didn't happen!" << endl;
cout << endl << endl;
}
{
printHeader("T4: Re-wrap a gift");
cout << "Attempting to rewrap the previous Gift: "
<< g1.m_description << endl;
if (wrap(g1) == false)
cout << "Test succeeded!";
else
cout << "Test failed: gift it's already wrapped, cannot wrap again!";
cout << endl << endl;
}
{
printHeader("T5: Unwrap a gift");
cout << "Attempting to unwrap the previous gift: "
<< g1.m_description << endl;
if (unwrap(g1))
cout << "Test succeeded!";
else
cout << "Test failed: you should be able to unwrap!";
cout << endl << endl;
}
{
printHeader("T6: Unwrap again");
cout << "Attempting to un-unwrap the previous gift: "
<< g1.m_description << endl;
if (!unwrap(g1))
cout << "Test succeeded!";
else
cout << "Test failed: you should not be able to unwrap again!";
cout << endl << endl;
}
Gift g2; // Unwrapped Gift
{
printHeader("T7: Prepare another gift");
g2.m_wrap = nullptr;
g2.m_wrapLayers = 0;
gifting(g2);
cout << endl;
display(g2);
cout << endl;
}
{
printHeader("T8: Unwrap the second gift");
unwrap(g2);
}
return 0;
}
Output matches perfectly but I don't know why memory leaks.. please help me. I am doubting my wrap part but I think there must be something else since deallocation seems fine.
I tried my best but I still cannot see which part is wrong.
I cannot see why my deallocation does not work I tried changing it so many times but nothing works.
On this line:
m_wrap.m_wrap->m_pattern = new char[MAX_WRAP + 1];
You allocate memory, but later you only:
delete[]m_wrap.m_wrap;
Also in your for loop you allocate memory, then get some input and store that inside the pointer, as a memory address. Should you ever dereference that, you will invoke undefined behavior, in practice that may likely will a segfault. You should consider rewriting at least that part from scratch.

Why is failed input validation returning me to the start of my program?

Really sorry if this is a dumb question. I know it must have a super easy solution but I've been staring at this for so long I can't see it. It doesn't help that I'm really new at this either.
Long story short for some reason entering an invalid input past the first time returns me back to my menu, and sometimes also asks me to enter weight immediately after instead of allowing me to enter a menu choice. It's just all around broken and I don't know why. Thanks.
#include <iostream>
#include <iomanip>
#include <limits>
using namespace std;
bool loopFlag = true;
bool loopFlagTwo = true;
int choice = 0;
int time = 0;
float weightPounds = 0;
float weight = 0;
const int BIKING = 8;
const int RUNNING = 10;
const int LIFTING = 3;
const float YOGA = 2.5;
int main()
{
cout << "Welcome to my Fitness Center" << endl;
do
{
cout << "\n\t____________________________________________________________" << endl;
cout << "\n\t\t\tMy Fitness Center" << endl;
cout << "\t\t\tActivity System" << endl;
cout << "\t____________________________________________________________" << endl;
cout << "\t\t\t Main Menu\n" << endl;
cout << "\t\t\t1) Stationary Bike" << endl;
cout << "\t\t\t2) Treadmill" << endl;
cout << "\t\t\t3) Weight Lifting" << endl;
cout << "\t\t\t4) Hatha Yoga" << endl;
cout << "\t\t\t5) End" << endl;
cout << "\t____________________________________________________________" << endl;
cout << "\n\nEnter the workout that you wish to track, or end to exit:" << endl;
do
{
cin >> choice;
if (cin.fail() || choice > 5 || choice < 1)
{
cout << "Invalid choice. Please choose from option 1 through 5." << endl;
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
else if (choice == 5)
{
return 0;
}
else
{
loopFlag = false;
}
}
while (loopFlag);
do
{
cout << "\nPlease enter your weight in pounds: " << endl;
cin >> weightPounds;
if (cin.fail() || weightPounds <= 0)
{
cout << "Invalid weight entry!" << endl;
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
else
{
loopFlag = false;
}
}
while (loopFlag);
weight = weightPounds / 2.2;
cout << "\nYour weight is: \n" << fixed << setprecision(1) << weight << " kilograms." << endl;
if (choice == 1)
{
do
{
cout << "For how many minutes did you do this activity? " << endl;
cin >> time;
if (cin.fail() || time <= 0)
{
cout << "Invalid time entry!" << endl;
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
else
{
loopFlag = false;
}
}
while (loopFlag);
}
}
while (choice != 5);
return 0;
}
You need to set loopFlag to true before every do...while() you have, or use another flag, because after the first do...while(), loopFlag is always false.

While loops expression

I'm trying to write a program that asks the user to enter digits between 0 and 1000000 and it outputs the occurrence of a certain number (that the user entered as well)
I've wrote this program and I believe it works well, but I have one issue which is if the while expression is not true, I want to cout a certain message but I don't know where to place it.
Here's my program:
#include <iostream>
using namespace std;
int main()
{
int n,j=0,key;
cout << "Pleaser enter digits\n";
cin >> n;
cout << "please enter key number\n";
cin >> key;
while (n>0 && n<1000000)
{
if(n%10==key)j++;
n= n/10;
}
cout << "The number " << key << " was found " << j << " time(s)" << endl;
return 0;
}
Thanks in advance!
Use
if(n>0 && n<1000000)
{
while(n)
{
if(n%10==key)
j++;
n= n/10;
}
}
else
cout<<"n is supposed to be between 0 and 1000000";
As there are no breaks (or no other piece of code that can jump) inside the bucle, everything after the while structure is executed because the expression returned false.
while (n>0 && n<1000000)
{
if(n%10==key)j++;
n= n/10;
}
cout << "While expression not anymore true" << endl;
cout << "The number " << key << " was found " << j << " time(s)" << endl;
return 0;
}
UPDATE
Based on the comments, it seems that you want to check if the number entered is valid or not. Simply, just check it before the while:
if(not (n>0 and n<1000000)) cout << "Number must be between 0 and 1000000" << endl;
else {
while (n)
{
if(n%10==key)j++;
n= n/10;
}
}
cout << "The number " << key << " was found " << j << " time(s)" << endl;
return 0;
}
Write a if statement before while loop.
if(!(n>0 && n<1000000))
{
cout << "....";
return -1;
}
while(..)

C++ program to display votes in percentage not showing correct result

I'm solving some C++ problems from ebooks. I made this C++ program but it isn't working properly. I've 2 problems:
Even after applying the forumla (votePercentage = firstAnswer/totalVotes*100;) it isn't showing the output, but only 0.
The program should display the bar chart, how am I suppose to do that? Any hints, reference or solution will be appreciated.
Here is my code:
/*
* Write a program that provides the option of tallying up the
* results of a poll with 3 possible values.
* The first input to the program is the poll question;
* the next three inputs are the possible answers.
* The first answer is indicated by 1, the second by 2, the third by 3.
* The answers are tallied until a 0 is entered.
* The program should then show the results of the poll—try making
* a bar graph that shows the results properly scaled to fit on
* your screen no matter how many results were entered.
*/
#include <iostream>
#include <string>
void startPoll (void);
void showPoll (void);
void pollCheck (void);
std::string pollQuestion, answer1, answer2, answer3;
int pollChoice, firstAnswer, secondAnswer, thirdAnswer;
int main (void)
{
int totalVotes = 1;
float votePercentage;
startPoll();
showPoll();
for(;;totalVotes++)
{
if (pollChoice == 1)
{
firstAnswer = firstAnswer + 1;
}
else if (pollChoice == 2)
{
secondAnswer++;
}
else if (pollChoice == 3)
{
thirdAnswer++;
}
else
{
std::cout << "==============*======*======*==============\n"
<< " RESULT \n"
<< "==============*======*======*==============\n"
<< "Question: " << pollQuestion << "\n"
<< "Total Votes: " << totalVotes << "\n";
votePercentage = (firstAnswer/totalVotes)*100;
std::cout << answer1 << ": " << firstAnswer << " votes. | " << votePercentage << "\n";
votePercentage = secondAnswer/totalVotes*100;
std::cout << answer2 << ": " << secondAnswer << " votes. | " << votePercentage << "\n";
votePercentage = thirdAnswer/totalVotes*100;
std::cout << answer3 << ": " << thirdAnswer << " votes. | " << votePercentage << "\n";
return 0;
}
std::cout << "\nEnter your vote again\nOR\nuse 0 to show the results.\n";
std::cin >> pollChoice;
}
std::cout << "Error: Something went wrong!\n";
}
void startPoll (void)
{
std::cout << "Enter your poll question:\n";
getline (std::cin, pollQuestion, '\n');
std::cout << "Enter answer 1:\n";
getline (std::cin, answer1, '\n');
std::cout << "Enter answer 2:\n";
getline (std::cin, answer2, '\n');
std::cout << "Enter answer 3:\n";
getline (std::cin, answer3, '\n');
}
void showPoll (void)
{
std::cout << "==============|======|======|==============\n"
<< " POLL \n"
<< "==============|======|======|==============\n"
<< pollQuestion << "\n"
<< "1. " << answer1 << "\n"
<< "2. " << answer2 << "\n"
<< "3. " << answer3 << "\n\n"
<< "Enter 1,2 or 3:\n\n";
std::cin >> pollChoice;
pollCheck();
}
void pollCheck (void)
{
if (pollChoice != 1 && pollChoice != 2 && pollChoice != 3)
{
std::cout << "Wrong choice entered! Please try again.\n\n";
return showPoll();
}
}
You need to take care that integer/integer = integer. In your case, changing
(firstAnswer/totalVotes)*100
to
(1.0*firstAnswer/totalVotes)*100
or
(firstAnswer*100.0/totalVotes)
should work. They all give a floating point result.
Well, the solution for the Bar Chart could be the following:(Not written by me) I think thats very self explaining because its really basic
void line (int n, char c)
{
// this is the loop for n
for (int i = 0; i < n; i++)
cout << c << endl;
}
Here is my solution, you can see how I made the bars work by reading the comments.
#include <iostream>
using namespace std;
int main()
{
int a = 0;
int b = 0;
int c = 0;
cout << "What is your favorite animal? 1 Cat, ";
cout <<"2 Dog, 3 Fish, 0 Count votes" << endl;
//Choice counter
while (true)
{
int choice;
cout << "Choice: ";
cin >> choice;
if(choice == 1)
a++;
else if(choice == 2)
b++;
else if(choice == 3)
c++;
else if(choice == 0)
break;
else
continue;
}
cout << endl << " 1: " << a << endl;
cout << " 2: " << b << endl;
cout << " 3: " << c << endl;
cout << endl << "1\t" << "2\t" << "3\t" << endl;
//Finds the max voted option
int max = 0;
if(a > b && a > c)
max = a;
else if(b > c && b > a)
max = b;
else if(c > a && c > b)
max = c;
/* If the max voted option is bigger than 10, find by how much
we have to divide to scale the graph, also making 10 bar
units the max a bar can reach before scaling the others too */
int div =2;
if(max > 10)
{
do
{
max = max/div;
if(max < 10)
break;
div++;
}while(true);
}else
div = 1;
//Sets the final number for the bars
a=a/div;
b=b/div;
c=c/div;
if(a==0)
a++;
if(b==0)
b++;
if(c==0)
c++;
//Creates the bars
while(true)
{
if(a>0)
{
cout << "[]" << "\t";
a--;
}else
cout << " ";
if(b>0)
{
cout << "[]" << "\t";
b--;
}else
cout << " ";
if(c>0)
{
cout << "[]" << "\t";
c--;
}else
cout << " ";
cout << endl;
if(a==0 && b==0 && c==0)
break;
}
}