一切都很好,但有一个主要问题。当验证用户输入以检查用户是否输入了正确的值(即字符串的字符,整数的数字)时,代码只能检测用户何时错误地输入了字符串,而不能检测到整数。这意味着只要用户输入年龄整数,代码就不会验证输入。
这是我的代码。
#include <iostream>
#include <limits>
#include <string>
using namespace std;
string firstName, secondName, homeTown;
int age;
int main() {
do {
cout << "Please enter your full name, hometown and age (e.g. John Doe London 25).\n\n";
cin >> firstName >> secondName >> homeTown >> age;
if (cin.fail()) {
cout << "\nInvalid input!\n\n";
cin.clear();
cin.ignore();
}
else {
break;
}
} while (1);
cout << "\nYour Name is: " << firstName << " " << secondName << "\n" << "Your Hometown is: " << homeTown << "\n" << "Your Age is: " << age << "\n";
return 0;
}
以下是当所有内容输入正确时它如何输出的示例:
Please enter your full name, hometown and age (e.g. John Doe London 25).
John Doe London 25
Your Name is: John Doe
Your Hometown is: London
Your Age is: 25
这里是当只有整数输入错误时如何输出的示例:
Please enter your full name, hometown and age (e.g. John Doe London 25).
1 1 1 a
Invalid input!
Please enter your full name, hometown and age (e.g. John Doe London 25).
这里是主要问题,只要正确输入整数,无论字符串如何输入,我得到的输出都是:
Please enter your full name, hometown and age (e.g. John Doe London 25).
1 1 1 1
Your Name is: 1 1
Your Hometown is: 1
Your Age is: 1
总而言之,我到底如何使用 if 语句验证整数和多个字符串?
我到底如何使用 if 语句验证整数和多个字符串?
当您需要验证用户所做的输入时,通常最好一次输入一个。这样,您可以在输入时检查每一项,并在其中一项无效时要求用户重试。
我通常为我希望用户输入的每个输入调用专用函数。例如,函数
get_int
显示提示,并不断循环,直到用户输入有效数字。条目必须位于 min
和 max
之间,否则用户必须重试!
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');
return n;
}
}
}
这是一个非常相似的输入字符串的函数。它使用
std::getline
,允许字符串条目包含空格。这样,您就不必分别输入名字和姓氏(除非您愿意)。条目不得为空。
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 {
return s;
}
}
}
使用上面的两个函数可以让你简化函数
main
。请注意,我已经省略了using namespace std;
。大多数专业人士都远离它。我还消除了全局变量。它们在像这个这样的小程序中可能没问题,但在较大的程序中可能会很糟糕,因为错误可能很难追踪。
// 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');
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 {
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
第一次运行时没有出现错误。
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
第二次,错误比比皆是。此运行显示输入全名而不是单独的名字和姓氏的问题。无法检测到姓氏是否被省略。
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: 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