I'm writing a program that calculates the cost of a purchase based on user input. If the user uses negative or otherwise invalid values for price and quantity the program should print an error and ask again.
#include <iostream>
#include <string>
#include <cmath>
#include <limits>
#include <algorithm>
using namespace std;
bool validatePrice(const string& str) {
if (str.find_first_not_of("0123456789.") != string::npos) {
return false;
} else if (stof(str) <= 0.0) {
return false;
} else {
return true;
}
}
bool validateQuantity(const string& str) {
if (all_of(str.begin(), str.end(), ::isdigit)) {
if (stoi(str) < 1) {
return false;
} else {
return true;
}
} else {
return false;
}
}
int main() {
const float NYTAX = .0875;
string p;
string q;
float price = -1;
int quantity = -1;
float subTotal;
float total;
cout << "enter price: ";
while (price == -1) {
cin >> p;
if (!(validatePrice(p))) {
cout << "error, try a positive number.\n";
cout << "enter price: ";
} else {
price = stof(p);
}
}
cout << "enter quantity: ";
while (quantity == -1) {
cin >> q;
if (!(validateQuantity(q))) {
cout << "error, try a positive whole number.\n";
cout << "enter quantity: ";
} else {
quantity = stoi(q);
}
}
subTotal = price * quantity;
total = (round(subTotal (subTotal * NYTAX)) * 100) / 100;
cout << "Your total is " << total;
}
My problem is twofold. Should I type in "3.00 d" for price, the console prints this:
enter quantity: error, try a positive whole number
enter quantity:
"3.00 d" has a space and an alphabetical character, so str.find_first_not_of() should return 5. Thus my if condition in validatePrice() should evaluate to false, no? Part two to this issue is that validateQuantity() is called even though the console should be waiting for me to enter quantity first. This only happens when I mess up the price.
Any other amendments to my code (best practices, simplify) would be appreciated.
CodePudding user response:
std::cin << string
by default reads up to the first whitespace. Note that if you print str
inside validatePrice()
, it won't be the full input you specified.
You should use std::getline()
instead to read an entire line.