How exactly do I go about validating both an integer and multiple strings with an if statement?
When you need to validate the entries made by a user, you are usually better off inputting them one at a time. That way, you can check each one as it is entered, and ask the user to try again, when one of them is invalid.
I generally call a dedicated function for each input I want the user to enter. Function get_int, for instance, displays a prompt, and keeps looping until the user has entered a valid number. Entries must lie be between min and max, or else the user has to try again!
int get_int(
std::string const& prompt,
int const min,
int const max)
{
for (;;) {
std::cout << prompt;
if (int n{}; !(std::cin >> n)) {
std::cout << "Invalid entry. Please reenter.\n\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
else if (n < min || n > max) {
std::cout << "Invalid entry. Please reenter.\n"
<< "Entries must be between " << min << " and " << max << ".\n\n";
}
else {
// The call to `ignore` ensures that this function "plays nice"
// with `std::getline`.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << '\n';
return n;
}
}
}
Here is a very similar function that inputs strings. It uses std::getline, which allows string entries to contain spaces. That way, you do not have to input first and last names separately (unless you want to). Entries are not allowed to be blank.
std::string get_non_empty_string(std::string const& prompt)
{
for (;;) {
std::cout << prompt;
if (std::string s; !(std::getline(std::cin, s))) {
throw std::runtime_error{ "get_non_empty_string: `std::getline` failed" };
}
else if (s.empty()) {
std::cout << "Invalid entry. Please reenter.\n"
<< "Entries cannot be blank.\n\n";
}
else {
std::cout << '\n';
return s;
}
}
}
A complete program
Using the two functions above allows you to simplify function main. Note that I have dispensed with using namespace std;. Most professionals stay away from it. I have also eliminated the global variables. They may be okay in a small program such as this one, but they can be nasty in larger programs, where mistakes can be difficult to track down.
// main.cpp
#include <iostream>
#include <limits>
#include <stdexcept>
#include <string>
//==================================================================
// get_int
//==================================================================
int get_int(
std::string const& prompt,
int const min,
int const max)
{
for (;;) {
std::cout << prompt;
if (int n{}; !(std::cin >> n)) {
std::cout << "Invalid entry. Please reenter.\n\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
else if (n < min || n > max) {
std::cout << "Invalid entry. Please reenter.\n"
<< "Entries must be between " << min << " and " << max << ".\n\n";
}
else {
// The call to `ignore` ensures that this function "plays nice"
// with `std::getline`.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << '\n';
return n;
}
}
}
//==================================================================
// get_non_empty_string
//==================================================================
std::string get_non_empty_string(std::string const& prompt)
{
for (;;) {
std::cout << prompt;
if (std::string s; !(std::getline(std::cin, s))) {
throw std::runtime_error{ "get_non_empty_string: `std::getline` failed" };
}
else if (s.empty()) {
std::cout << "Invalid entry. Please reenter.\n"
<< "Entries cannot be blank.\n\n";
}
else {
std::cout << '\n';
return s;
}
}
}
//==================================================================
// main
//==================================================================
int main() {
std::cout << "Please tell us about yourself.\n\n";
std::string full_name = get_non_empty_string("Full name: ");
std::string hometown = get_non_empty_string("Hometown: ");
int age = get_int("Age: ", 0, 125);
std::cout
<< "\nYour Name is: " << full_name<< "\n"
<< "Your Hometown is: " << hometown << "\n"
<< "Your Age is: " << age << "\n";
return 0;
}
// end file: main.cpp
Sample output
No errors were made during the first run.
Please tell us about yourself.
Full name: Joe Dokes
Hometown: London
Age: 25
Your Name is: Joe Dokes
Your Hometown is: London
Your Age is: 25
The second time around, mistakes abounded. This run shows the problem with inputting full name, rather than separate first and last names. There was no way to detect that the last name was omitted.
Please tell us about yourself.
Full name:
Invalid entry. Please reenter.
Entries cannot be blank.
Full name: Joe
Hometown:
Invalid entry. Please reenter.
Entries cannot be blank.
Hometown: London, England
Age: xxx
Invalid entry. Please reenter.
Age: 1000
Invalid entry. Please reenter.
Entries must be between 0 and 125.
Age: 25
Your Name is: Joe
Your Hometown is: London, England
Your Age is: 25
"1"cause any problem with input? Perhaps after input you need to check if thefirstName,secondNameandhomeTownvariables are made up of nothing but digits. Perhaps using find_first_not_of()? E.g.if (firstName.find_first_not_of ("0123456789") != std::string::npos) { // firstName is all digits }std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');to ensure all extraneous characters are removed instead of just one. While fine for short example programs, make sure you visit Why is “using namespace std;” considered bad practice?if (firstName.find_first_of("123456789") != std::string::npos || secondName.find_first_of("123456789") != std::string::npos || homeTown.find_first_of("123456789") != std::string::npos) {is the code I wrote. Only issue now is the opposite is happening, where the code isn't detecting the integer being inputted incorrectly (e.g. I enter "a" for age and it returns the input as successful instead of invalid)1 1 1 ais "an example [...] when only the integer is inputted incorrectly" which implies that1 1 1is correct for the strings, and yet your last example implies that1 1 1is not correct for the strings.