整数输入验证 - 拒绝非整数输入并在 C++ 中请求另一个输入?
Integer input validation - Rejecting non integer input and requesting another in C++?
当 valid_office_num 为 false 时,此函数不断在 while 循环内的另一个函数中调用。问题是,如果输入以数字开头但后面跟着其他无效字符(例如 5t),它会采用数字部分并将其接受为有效输入。我希望它考虑整个输入并拒绝它,以便它可以请求另一个。我以为我可以使用 getline() 但后来我不能使用 cin.fail()。我该如何实现这种行为?
我忘了说我是 C++ 的新手,到目前为止我只学了基础知识。
(需要明确的是,期望的行为是拒绝任何包含数字以外的任何内容。这不是整数范围检查问题。如果它不是整数,请丢弃它并请求另一个)
//Function to read a valid office number, entered by user
int read_office_num()
{
//Declaration of a local variable
int office_num;
//Read input
cin >> office_num;
//Check if input was valid
if (cin.fail())
{
//Print error message
cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n";
//Clear error flags
cin.clear();
//Ignore any whitespace left on input stream by cin
cin.ignore(256, '\n');
}
else
{
//Office number entered is valid
valid_office_num = true;
}
return office_num;
}
嗯。我可能遗漏了一些东西,但为什么不读一行,trim 它,使用正则表达式来验证一个数字,然后利用 strstream 的设施或者如果必须的话只利用 atoi?在所有现实中,我可能只是让用户摆脱无关的输入(但如果我确定我总是以交互方式 运行ning 则丢弃它)。遵循座右铭 "be lenient in what you accept."
"interactive" 警告很重要。人们通常不能假设 cin 是终端。有人可能会变得自大,让您的程序 运行 在文本文件或管道中运行,然后它就会失败。一种稳健的方法会将数据处理(便携式)与输入方式(可能是特定于机器的,因此也比通过控制台 stdin/stdout 更强大和有用)分开。
您可以使用 stringstream
int read_office_num()
{
//Declaration of a local variable
int office_num;
string input = "";
while (true) {
getline(cin, input);
stringstream myStream(input);
if (myStream >> office_num)
break;
cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n" << endl;
}
return office_num;
}
如果你想拒绝像 123 xxx
这样的输入,你可以添加一个额外的检查来验证接收到的字符串确实是一个整数:
bool is_number(const string& s)
{
string::const_iterator itr = s.begin();
while (itr != s.end() && isdigit(*itr)) ++itr;
return !s.empty() && itr == s.end();
}
int read_office_num()
{
//Declaration of a local variable
int office_num;
string input = "";
while (true) {
getline(cin, input);
stringstream myStream(input);
if (is_number(input) && myStream >> office_num)
break;
cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n" << endl;
}
return office_num;
}
据我了解,您希望将整行作为数字读取,否则会失败?
嗯,你可以使用std::getline()
,但你必须遵循下面的算法(我会把实现留给你..)
- 使用
std::getline(cin, str)
读取一行,如果return为真
- 使用
std::stoi(str, &pos)
转换为整数并获取最后一个整数的位置
- 如果
pos != str.size()
则整行不是整数(或者如果上面抛出异常),则它不是有效整数,否则 return 值...
使用 std::getline()
.
将一行输入读取为 std::string
检查字符串并检查它是否包含任何非数字字符。
如果字符串只包含数字,使用std::istringstream
从字符串中读取一个整数。否则报告失败,或采取任何其他需要的恢复操作(例如丢弃整个字符串并 return 读取另一个)。
您可能应该只查看 cin
中剩余的输入字符数。你可以用 in_avail
你的函数最终可能会有一个像这样的主体:
//Declaration of a local variable
int office_num;
//Read input and check if input was valid
for (cin >> office_num; cin.rdbuf()->in_avail() > 1; cin >> office_num){
//Print error message
cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n";
//Ignore any whitespace left on input stream by cin
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
//Office number entered is valid
valid_office_num = true;
return office_num;
兴趣点:
cin
中始终至少有 1 个字符,否则 cin
将被标记为 bad
,这样就不好了
- 如果
read_office_num
以这种方式实现,则不需要 valid_office_num
,因为 valid_office_num
在返回 之前将始终设置为 true
使用 Boost Lexical Cast 的方法如下:
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <vector>
#include <string>
int read_office_num()
{
using boost::lexical_cast;
using boost::bad_lexical_cast;
using namespace std;
int office_num;
while (true)
{
try
{
string input = cin.getline();
office_num = lexical_cast<int>(*argv));
break;
}
catch(const& bad_lexical_cast)
{
cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n";
}
}
return office_num;
}
当 valid_office_num 为 false 时,此函数不断在 while 循环内的另一个函数中调用。问题是,如果输入以数字开头但后面跟着其他无效字符(例如 5t),它会采用数字部分并将其接受为有效输入。我希望它考虑整个输入并拒绝它,以便它可以请求另一个。我以为我可以使用 getline() 但后来我不能使用 cin.fail()。我该如何实现这种行为?
我忘了说我是 C++ 的新手,到目前为止我只学了基础知识。
(需要明确的是,期望的行为是拒绝任何包含数字以外的任何内容。这不是整数范围检查问题。如果它不是整数,请丢弃它并请求另一个)
//Function to read a valid office number, entered by user
int read_office_num()
{
//Declaration of a local variable
int office_num;
//Read input
cin >> office_num;
//Check if input was valid
if (cin.fail())
{
//Print error message
cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n";
//Clear error flags
cin.clear();
//Ignore any whitespace left on input stream by cin
cin.ignore(256, '\n');
}
else
{
//Office number entered is valid
valid_office_num = true;
}
return office_num;
}
嗯。我可能遗漏了一些东西,但为什么不读一行,trim 它,使用正则表达式来验证一个数字,然后利用 strstream 的设施或者如果必须的话只利用 atoi?在所有现实中,我可能只是让用户摆脱无关的输入(但如果我确定我总是以交互方式 运行ning 则丢弃它)。遵循座右铭 "be lenient in what you accept."
"interactive" 警告很重要。人们通常不能假设 cin 是终端。有人可能会变得自大,让您的程序 运行 在文本文件或管道中运行,然后它就会失败。一种稳健的方法会将数据处理(便携式)与输入方式(可能是特定于机器的,因此也比通过控制台 stdin/stdout 更强大和有用)分开。
您可以使用 stringstream
int read_office_num()
{
//Declaration of a local variable
int office_num;
string input = "";
while (true) {
getline(cin, input);
stringstream myStream(input);
if (myStream >> office_num)
break;
cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n" << endl;
}
return office_num;
}
如果你想拒绝像 123 xxx
这样的输入,你可以添加一个额外的检查来验证接收到的字符串确实是一个整数:
bool is_number(const string& s)
{
string::const_iterator itr = s.begin();
while (itr != s.end() && isdigit(*itr)) ++itr;
return !s.empty() && itr == s.end();
}
int read_office_num()
{
//Declaration of a local variable
int office_num;
string input = "";
while (true) {
getline(cin, input);
stringstream myStream(input);
if (is_number(input) && myStream >> office_num)
break;
cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n" << endl;
}
return office_num;
}
据我了解,您希望将整行作为数字读取,否则会失败?
嗯,你可以使用std::getline()
,但你必须遵循下面的算法(我会把实现留给你..)
- 使用
std::getline(cin, str)
读取一行,如果return为真 - 使用
std::stoi(str, &pos)
转换为整数并获取最后一个整数的位置 - 如果
pos != str.size()
则整行不是整数(或者如果上面抛出异常),则它不是有效整数,否则 return 值...
使用 std::getline()
.
std::string
检查字符串并检查它是否包含任何非数字字符。
如果字符串只包含数字,使用std::istringstream
从字符串中读取一个整数。否则报告失败,或采取任何其他需要的恢复操作(例如丢弃整个字符串并 return 读取另一个)。
您可能应该只查看 cin
中剩余的输入字符数。你可以用 in_avail
你的函数最终可能会有一个像这样的主体:
//Declaration of a local variable
int office_num;
//Read input and check if input was valid
for (cin >> office_num; cin.rdbuf()->in_avail() > 1; cin >> office_num){
//Print error message
cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n";
//Ignore any whitespace left on input stream by cin
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
//Office number entered is valid
valid_office_num = true;
return office_num;
兴趣点:
cin
中始终至少有 1 个字符,否则cin
将被标记为bad
,这样就不好了- 如果
read_office_num
以这种方式实现,则不需要valid_office_num
,因为valid_office_num
在返回 之前将始终设置为
true
使用 Boost Lexical Cast 的方法如下:
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <vector>
#include <string>
int read_office_num()
{
using boost::lexical_cast;
using boost::bad_lexical_cast;
using namespace std;
int office_num;
while (true)
{
try
{
string input = cin.getline();
office_num = lexical_cast<int>(*argv));
break;
}
catch(const& bad_lexical_cast)
{
cout << "\nInvalid office number, it should only consist of digits!! Enter another:\n";
}
}
return office_num;
}