limit item entry C++ - c++

need to limit the ammount of items that can be entered into the array to 5. Tought i would use a do while loop but it just continues even after the 5 items have been entered. Any help would be appreciated
#include "stdafx.h"
#include <string>
#include <conio.h>
#include <iostream>
#include <array>
using namespace std;
string sItems[4] = {};
string sChoice = "";
int iItemPrice[4] = {};
int iNumOfItems = 0;
int iMenuChoice = 0;
int iCount = 0;
int main()
{
cout << "--------- Welcome to the program ---------\n\n Please pick from an option below: \n 1: Enter new items \n 2: Change item prices \n 3: Input sold items \n 4: Receipt for previous items sold\n ";
cin >> iMenuChoice;
switch (iMenuChoice)
{
case 1:
{
do {
cout << "--------- ENTER NEW ITEMS ---------\n\nPlease enter the item Name: ";
cin >> sItems[iCount];
cout << "\nPlease enter the price of: " << sItems[iCount] << "\n";
cin >> iItemPrice[iCount];
cout << "\nWould you like to enter another item? Y/N \n";
cin >> sChoice;
if (sChoice == "Y" || sChoice == "y")
{
++iCount;
++iNumOfItems;
}
} while (sChoice == "Y" || sChoice == "y" || iNumOfItems < 5);
cout << "you have entered the maximum ammount of items";
}
}
_getch();
return 0;
}

The loop condition sChoice == "Y" || sChoice == "y" || iNumOfItems < 5 means:
Loop as long as user answers "Y"
But at least 5 times regardless of user answer
If you want some other logic, like loop up to 5 times, then you can reflect that in the code.
Also check for failures. If you input a character when cin expects a number, it will enter a failed state and all subsequent input attempts will fail.
do {
cout << "--------- ENTER NEW ITEMS ---------\n\nPlease enter the item Name: ";
cin >> sItems[iCount];
cout << "\nPlease enter the price of: " << sItems[iCount] << "\n";
if (!(cin >> iItemPrice[iCount]))
break;
cout << "\nWould you like to enter another item? Y/N \n";
cin >> sChoice;
++iCount;
++iNumOfItems;
} while ((sChoice == "Y" || sChoice == "y") && iNumOfItems < 5);
And increase the array size from 4 to 5 if you want to support 5 items:
string sItems[5];
int iItemPrice[5];

Related

Non integer input causes infinite loop

i created a code for my final project. where in the start the user is asked what calculator to use its either the average calculator or simple calculator. but if the user accidentally entered a non integer it causes in infinite error loop but if its an integer that is not in the choices it works because i created a while loop. i need help what do i need to do to prevent the infinite loop.
cout << 1. average calculator: << endl;
cout << 2. simple calculator: << endl;
cout << Enter the Number << endl;
cin >> choice;
while (choice > 2 || choice <= 1)
{
cout << "Error! Please choose a number between 1 and 2 only." << endl;
cout << "Enter the number again:";
cin >> choice;
}
You need to clear the input buffer. Also the condition in this if statement is incorrect
while (choice > 2 || choice <= 1)
It seems you mean
while (choice > 2 || choice < 1)
The while loop can be rewritten as do-while loop the following way
#include <limits>
//...
bool input_error = false;
do
{
input_error = false;
if ( not ( std::cin >> choice ) )
{
std::cin.clear();
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
input_error = true;
}
else if ( choice < 1 || choice > 2 )
{
input_error = true;
}
if ( input_error )
{
std::cout << "Error! Please choose a number between 1 and 2 only.\n";
std::cout << "Enter the number again: ";
}
} while ( input_error );
Instead of using a while loop, you could use a switch like this
switch(choice //this is the input)
{
case 1:
//the stuff you want to do
break; //always a break
case 2:
//more stuff
break;
default:
//throwing a error
std::cout << "Error, please pick a number between 1 and 2\n";
}
and if you want to repeat until you pick the right number, you could put the switch inside a do while loop like this
do
{
switch(choice)
{
//the stuff
}
}while(choice > 2 || choice < 1);
let's hope this will work
have a nice day.
cout << "1. average calculator:" << endl;
cout << "2. simple calculator:" << endl;
cout << "Enter the Number" << endl;
string stringInput;
getline(cin, stringInput);
int choice = atoi(stringInput.c_str());
while(choice < 1 || choice > 2) {
cout << "Error! Please choose a number between 1 and 2 only." << endl;
cout << "Enter the number again:";
getline(cin, stringInput);
choice = atoi(stringInput.c_str());
}
You should read whole line, store it in string, and then convert that string to integer using atoi(). atoi() expects c-string to be passed so std::string should be converted to c-string. It is done by stringInput.c_str().
I changed while condition(choice > 2 || choice <= 1) to (choice < 1 || choice > 2) because it says to enter number between 1 and 2, but with your condition entering number 1 would print "Error! Please choose a number between 1 and 2 only.".

Looping assignment in C++

My assignment is utilizing loops. The program should accept input for the sales of 3 employees (Mary, Tom, and Chris). The flow should be as follows:
Initial? > number of sales to enter > enter sale amounts > display commission for sale at 17% > adds commission and sales to the respective variables >> continue until 'z' is input for inputSalesPerson >> display information
So I am trying to figure out why my return value for the tempComm variable isn't returning the correct value. If i was to enter 't' for variable inputSalesPerson it puts me into the switch case 't' no problem. Input number of sales and that works. But when I get to entering the salesAmount and then displaying commission it will not calculate correctly.
Also if I enter 'z' or 'Z' as the inputSalesPerson it will not end the program. I have a lot to go on this.
#include <iomanip>
#include <iostream>
using namespace std;
int main()
{
int salesT = 0, salesC = 0, salesM = 0;
double amountT = 0, amountC = 0, amountM = 0;
double commT = 0, commC = 0, commM = 0;
double commRate = (17/100);
int num_sales;
double salesAmount, totalSales, tempComm;
char inputSalesPerson;
do
{
cout << "Enter the sales person's initial (\"Z\" to quit): ";
cin >> inputSalesPerson;
while(inputSalesPerson != 't' && inputSalesPerson != 'T' && inputSalesPerson != 'm' && inputSalesPerson != 'M' && inputSalesPerson != 'c' && inputSalesPerson != 'C' && inputSalesPerson != 'z' && inputSalesPerson != 'Z')
{
cin.get();
system("cls");
cout << "Invalid input for employee. Please Input (T)om, (C)hris, (M)ary, or (Z) to End : ";
cin >> inputSalesPerson;
}
switch(inputSalesPerson)
{
case 't' :
case 'T' :
system("cls");
cout << "Enter the number of sales : ";
cin >> num_sales;
while(num_sales < 1 || num_sales > 5)
{
system("cls");
cout << "Invalid number of sales. Please enter a value between 1 and 5 : ";
cin >> num_sales;
}
salesT += num_sales;
for(int i = 0; i<num_sales; i++)
{
cin.get();
system("cls");
cout << "Enter the sale amount : ";
cin >> salesAmount;
while(salesAmount < 0)
{
cin.get();
system("cls");
cout << "Invalid sale amount. Please enter a positive amount : ";
cin >> salesAmount;
}
tempComm = salesAmount + (salesAmount * commRate);
cout << fixed << setprecision(2) << "Commission earned by tom on this sale is : " << tempComm << endl;
cin.get();
amountT += salesAmount + tempComm;
commT += tempComm;
totalSales += amountT;
}
break;
}
}while(inputSalesPerson != 'z' || 'Z');
return 0;
}
****EDIT****
Thank you for the information on single-step debugging. Thanks to that comment I was able to learn about using the debugging tool more in depth and that helped me get everything working a bit better.
I've commented your code at the areas that need fixing. Also, there's a problem with using cin.get() all over the place. I assume that you do this to discard the return character after each input. But if the standard input (cin) is empty when you call cin.get() it will block the program until something is input. This is what happens when you enter more than one num_sales:
for (int i = 0; i<num_sales; i++)
{
cin.get();
It handles the first fine, but on the second loop you get:
Enter the sale amount : 20
Commission earned by tom on this sale is : 23.40
// cin.get() blocks here, with no user instructions to enter the next sale amount
I've commented out all the cin.get(). It will still work the same because the cin operator >> discards whitespaces and newlines, so even if there is a \n newline character still in the buffer, the next time you do something like cin >> num_sales it will discard the newline anyway.
#include <iomanip>
#include <iostream>
using namespace std;
int main()
{
int salesT = 0, salesC = 0, salesM = 0;
double amountT = 0, amountC = 0, amountM = 0;
double commT = 0, commC = 0, commM = 0;
double commRate = (17 / 100.0); // Int divided by int will round to an int.
// commRate is 0.0. Divide by double instead (17 / 100.0)
int num_sales;
double salesAmount, totalSales = 0, tempComm; // totalSales needs to be initialised to
// zero, otherwise it holds a garbage value.
char inputSalesPerson;
do
{
cout << "Enter the sales person's initial (\"Z\" to quit): ";
cin >> inputSalesPerson;
while (inputSalesPerson != 't' && inputSalesPerson != 'T' && inputSalesPerson != 'm' && inputSalesPerson != 'M' && inputSalesPerson != 'c' && inputSalesPerson != 'C' && inputSalesPerson != 'z' && inputSalesPerson != 'Z')
{
//cin.get();
system("cls");
cout << "Invalid input for employee. Please Input (T)om, (C)hris, (M)ary, or (Z) to End : ";
cin >> inputSalesPerson;
}
switch (inputSalesPerson)
{
case 't':
case 'T':
system("cls");
cout << "Enter the number of sales : ";
cin >> num_sales;
while (num_sales < 1 || num_sales > 5)
{
system("cls");
cout << "Invalid number of sales. Please enter a value between 1 and 5 : ";
cin >> num_sales;
}
salesT += num_sales;
for (int i = 0; i<num_sales; i++)
{
//cin.get();
//system("cls");
cout << "Enter the amount for sale number " << i+1 << ": ";
cin >> salesAmount;
system("cls"); // I would put the clear here,
// Otherwise the user can't see the commission made by Tom
while (salesAmount < 0)
{
//cin.get();
system("cls");
cout << "Invalid sale amount. Please enter a positive amount : ";
cin >> salesAmount;
}
tempComm = salesAmount + (salesAmount * commRate);
cout << fixed << setprecision(2) << "Commission earned by tom on this sale is : " << tempComm << endl;
//cin.get();
amountT += salesAmount + tempComm;
commT += tempComm;
totalSales += amountT; // I think you mean to add salesAmount maybe?
}
break;
}
} //while (inputSalesPerson != 'z' || 'Z');
// Even if { this ^^^^} is false, ^^^ this is always
// 'Z' char will convert to bool, any non-zero value is true.
while (inputSalesPerson != 'z' && inputSalesPerson != 'Z');
return 0;
}

How to evaluate number greater than and less than in the same while loop?

// DiceRollProject.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <time.h>
using namespace std;
int diceRoll(int max); // function definition
int getValidInteger();// function definition
int main() {
srand(time(0)); // seed the random number generator
int exitProgram = 0;
int guess, rollValue;
int maxRollValue = 6;
cout << "Hello! Let's play a dice game. Let me do the first roll for you.\n" << endl;
rollValue = diceRoll(maxRollValue);
cout << "In this roll, you got: " << rollValue << "\n" << endl;
do {
rollValue = diceRoll(maxRollValue);
cout << "What's your guess for the next roll? Enter an integer between 1 and " << maxRollValue << ": ";
guess = getValidInteger();
// TODO: Validate input
if (guess > rollValue)
{
cout << "The guess was too high!";
}
if (guess < rollValue)
{
cout << "The guess was too low!";
}
if (guess == rollValue)
{
cout << "You guessed correctly, congrats!";
}
cout << "In this roll, you got: " << rollValue << "\n" << endl;
// TODO: Evaluate result
cout << "Enter 1 to exit or any other integer to continue rolling ";
exitProgram = getValidInteger();
cout << "\n";
if (exitProgram == 1)
{
cout << "Sorry to see you go. Have a wonderful day!\n" << endl;
}
} while (exitProgram != 1);
return 0;
}
// Roll the die
int diceRoll(int max) {
int rollValue;
rollValue = (rand() % max) + 1;
return rollValue;
}
// Check if user entered an integer
int getValidInteger() {
int userInput;
cin >> userInput;
while (userInput < 1) {
if (userInput < 1)
{
cout << "Please enter a number greater than or equal to 1\n";
}
if (userInput > 6)
{
cout << "Please enter a number less than or equal to 6\n";
}
}
if (cin.fail()) {
cin.clear();
cin.ignore();
cout << "Please enter an Integer only ";
cin >> userInput;
cout << "\n";
}
return userInput;
}
I have a dice roll guessing game, I'm trying to evaluate the users input, to make sure that they can't enter a number less than 1 and greater than 6, unfortunately, with just my if statements, they can still enter these numbers, although a string is displayed that the input is not valid, I want to make a while loop that keeps asking them to enter a valid number equal or greater than 1 and equal to and less than 6, if the user keeps inputting an incorrect number, the while loop will keep asking them for a valid number, until they do enter one, which will then run the program as normally.
First of all, inside the while loop you have dead code.
while (userInput < 1) {
if (userInput < 1)
{
cout << "Please enter a number greater than or equal to 1\n";
}
if (userInput > 6)
{
cout << "Please enter a number less than or equal to 6\n";
}
}
Within the loop body, the first if is always true and the second one is always false. You should enter in a loop when the user writes an invalid input. This happens when (userInput < 1 or userInput > 6)
After the evaluation of the while's condition, you should ask the user to write input
do {
cout << "Please enter an Integer only ";
cin >> userInput;
if (userInput < 1)
{
cout << "Please enter a number greater than or equal to 1\n";
}
if (userInput > 6)
{
cout << "Please enter a number less than or equal to 6\n";
}
}while(userInput < 1 || userInput > 6);
So your condition that will keep you in the while loop is if the person guesses too high or too low. Inside the while loop I would add the updating condition or statement that you would like to repeat. So in your case, "your guess is too high" or " your guess is too low" and ask for their input again. I am not a pro but I would keep it simple by constructing 2 while loops, one for too high and one for too low just like your if statements. literally you can just change your first two if statements to while loops and adding an few extra lines of cout to ask the person to guess again and validate their input. I hope this helped.
from what I've understood you are looking for something like this:
int main (){
int my_magic_number=(rand()%6)+1,usernumber=-1;
bool state;
while (usernumber!=my_magic_number){
cin>>usernumber;
state = (usernumber<1||usernumber>6);
while (state) {
cout<<"You entered a number outside the range [1,6] please try again\n";}
cin>>usernumber;
state = (usernumber<1||usernumber>6);
}
if (usernumber!=my_magic_number) {/* do whatever you want */}
} //while loop
} // main

Nested loops in C++ and user input

Pretty new here to programming, and I have an assignment where I need to achieve the following:
ask for total amount of people
get each of their names
allow user to enter up to 5 scores for each person
if there are less than 5 scores for a given person, inputting -100 will stop it
So far I have written this:
#include <iostream>
using namespace std;
int main() {
string personName;
int totalPerson, personScoreCounter;
double personGrade, personGradeTotal;
cout << "Input total amount of people: ";
cin >> totalPerson;
for (int person = 1; person <= totalPerson; person++)
{
cout << "Input name for person " << person << ": ";
getline(cin, personName);
cin.ignore();
while ( (personGrade != -100) && (personScoreCounter <= 5) )
{
cout << "Input up to 5 scores for " << personName << " (-100 to end): ";
cin >> personGrade;
if (personGrade >= 0 && personGrade <= 100) // valid range of scores
{
personGradeTotal += personGrade;
personScoreCounter++;
}
else
{
cout << "Input only scores from 0-100" << endl;
}
cout << "Input up to 5 scores for " << personName << " (-100 to end): ";
cin >> personGrade;
}
}
// calculate averages and other stuff in here.
return 0;
}
After getting their name, only the last cout inside the while loop seems to execute first, then it starts from the top and so on until the for loop hits the end depending on totalPerson. I know I'm missing a few things in here, probably in the order of operations and also the way I am executing my loops, but I just can't see it. Could any of you guys with experience in the language please give me any pointers as to what's happening here and how I can fix it? Thank you.
Inside your while group, you only want to use your cout line once (at the beginning looks good).
Your first check should be for ==-100 or similar, since as it is now, you'll get a "Input only scores from 0 to 100" message if you enter -100.
You should keep a cin.ignore(); call after each use of cin >> VARIABLE, since then you will drop the EoL character.
Example code:
#include <iostream>
using namespace std;
int main() {
int totalPerson;
cout << "Input total number of people: ";
cin >> totalPerson;
cin.ignore();
for (int person = 1; person <= totalPerson; person++)
{
int personScoreCounter=0;
double personGrade = -1, personGradeTotal=0;
string personName;
cout << "Input name for person " << person << ": ";
std::getline(cin, personName);
while ( (personGrade != -100) && (personScoreCounter < 5) )
{
cout << "Input up to 5 scores for " << personName << " (-100 to end): ";
cin >> personGrade;
cin.ignore();
if (personGrade == -100) {
break;
} else if (personGrade >= 0 && personGrade <= 100) {
personGradeTotal += personGrade;
personScoreCounter++;
} else {
cout << "Input only scores from 0-100" << endl;
}
}
// calculate averages and other stuff in here.
double avg = personGradeTotal / personScoreCounter;
cout << "Avg = " << avg << endl;
}
return 0;
}
Some of your variables also needed to move inside the for loop.
Additionally I changed the limits on the personScoreCounter to [0:4] rather than [1:5] - this way you can use it for averaging more easily.
You might also try cin.getline() instead of getline(std::cin , ... ):
int max_length = 30;
std::cin.getline(personName, max_length, '\n'); // \n is option termination.
This allows whitespaces in the input also.
http://www.cplusplus.com/reference/istream/istream/getline/

Creating a menu using vectors, strings and arrays while reading from 2 text files

Alright, I been trying to do this for a couple of hours but I'm not getting anywhere. First of
all, I have 2 text files that I need to read from a different function which is simple enough. Then for one of the text files, mainly the college.txt, I have to add it to a vector of strings; for the other text file(states.txt), I have to add the states to parallel arrays of strings.
The problem(This is related to the college.txt file) I have is how do I compare the strings the user inputs to the strings inside the vector since I have to validate whether or not the colleges/universities that the user inputs are on the list(and of course repeat it until the user decides to quit but that's also simple enough to do with a while loop).
Note1: Before you ask, The else/if with empty statements are empty because I want to focus on this problem first and then I will continue on with the program.
Note2: The IDE that I'm using is CodeBlocks
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
using namespace std;
bool DoesStringEqualVector(vector<string> total, string name)
{
for (unsigned int i=0; i < total.size(); ++i)
{
if (name == total[i])
return true;
}
return false;
}
void collegesUniversities(string)
{
ifstream campuses;
campuses.open("colleges.txt");
string schools;
vector<string> schoolVector;
if(!campuses)
cerr << "Error opening file. ";
else
{
while(campuses.good())
{
getline(campuses,schools, '\n');
schoolVector.push_back(schools);
cout << schools << endl;
}
}
DoesStringEqualVector(schoolVector, schools);
campuses.close();
}
int main()
{
char response;
string comparison;
int choice;
string userInput;
cout << "\nWelcome to my college and university search program.\n";
cout << "\nPress any button to continue.\n ";
system("pause>nul");
do
{
cout << "\nPress 1 to enter possible colleges and universities.";
cout << "\nPress 2 to find out how many colleges and universities";
cout << " appear in your state.\n";
cout << "Press 3 to find the total amount of colleges and";
cout << " universities in our list. ";
cout << "\nPress 4 to quit. ";
cin >> choice;
if(choice == 1)
{
do
{
cout << "\nEnter the name of your college/university. ";
cin >> userInput;
collegesUniversities(comparison);
if(userInput != comparison)
cout << "\nThis institution isn't on out list.\n ";
else
cout << "\nThis institution is on the list.\n";
cout << "\nWould you like to return to the menu?[Y/N] ";
cin >> response;
while(response != 'Y' && response != 'y' && response != 'N' &&
response != 'n')
{
cerr << "\nError, Invalid Input.";
cin >> response;
}
}
while(response != 'N' && response != 'n');
}
else if(choice == 2)
{
}
else if(choice == 3)
{
}
else if(choice == 4)
{
cout << "\nThank you for using my program. ";
cout << "Have a great day.\n ";
}
else
{
cerr << "\nError, Invalid input. ";
cout << "Only integers from 1 through 4 are allowed.\n";
}
}
while(choice != 4);
}
Wrap it all up in a method that checks through the vector:
bool IsStringInVector(vector <string> collection, string item)
{
for (int i=0; i < collection.size(); ++i)
{
if (item == collection[i])
return true;
}
return false;
}
You have to scan through the collection to see if it's in there.