我正在使用带有地图的应用程序,但不希望某人能够在地图上输入无效的点(想想纬度和经度)。
假设您有一个看起来像这样的面板。不要以代码方式注意它的外观,而要注意看应用程序时的外观:
[My great application]
Textbox1 [XX:XX:XX]
Textbox2 [XX:XX:XX]
Textbox3 [XX:XX:XX]
Pushbutton [APPLY]
我无法知道是否有人在文本框中输入了正确的内容。我的文本框期望3套整数[XX:XX:XX]。不得低于00,且不得高于99(严格为2位数字)。对于此示例,我只会在int上显示以使其简短:
int myInt = NULL; //Don't want garbage data here
bool isValid = false;
//Gets input and sets textbox to myInt
std::string myString = std::to_string(myInt); //Cast int to a string
If(myString.length() - 1 == 0) //NULL intToString.length() == 1?
{
std::cout << "Incorrect, please try again" << std::endl;
}
else
{
isValid = true;
}
if(isValid)
{
//applyChanges(); <-- MY INTS WOULD GO INTO THIS
}
然后我很快意识到0-9是完全有效的。 (00,01,...,09)。所以这行不通。
我如何测试用户输入的内容是否正确?对我来说这不太有意义。除了测试长度,我不确定还能做些什么。
总而言之,我想找到一种获得条件的方法,以便当一切都好时,然后isValid = true;
答案 0 :(得分:1)
这是我想出的解决方案。如果我误解了您的问题,请告诉我。
算法很简单:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
// Simple string split algorithm
std::vector<std::string> string_split(
std::string const& str,
char delimiter)
{
std::istringstream ss{str};
std::vector<std::string> result;
std::string line;
while(std::getline(ss, line, delimiter)) {
result.emplace_back(std::move(line));
}
return result;
}
// Validates the input
bool isValid(std::string const& input) {
// Split string on each ':'
// 00:00:00
// ^ ^
auto substr = string_split(input, ':');
// If there are not 3 parts, its malformed
if(substr.size() != 3)
return false;
// For reach result...
for(auto const& str : substr) {
// If it is not 2 digits long, error.
if(str.size() != 2)
return false;
try {
// Try converting it to an integer
// This throws on failure
auto value = std::stoi(str);
// make sure its within range
return value >= 0 && value <= 99;
} catch(...) {
// Failed to convert
return false;
}
}
return true;
}
int main()
{
// Some tests
std::vector<std::string> inputs{
"00:00:00",
"99:99:99",
"1:00:00",
"AA:00:00",
"0B:0000",
"0B:00c00",
};
// Run tests and print result
for(auto& input : inputs) {
if(isValid(input)) {
std::cout << input << " - Valid!"<< std::endl;
} else {
std::cout << input << " - Invalid!"<< std::endl;
}
}
}
结果:
$g++ -o main *.cpp
$main
00:00:00 - Valid!
99:99:99 - Valid!
1:00:00 - Invalid!
AA:00:00 - Invalid!
0B:0000 - Invalid!
0B:00c00 - Invalid!
希望这会有所帮助,
干杯。
答案 1 :(得分:1)
我同意markhc,但您也可能喜欢使用正则表达式的处理方式。好处是,相同的代码也可以用于验证其他类型的输入,并且当然要短得多。
这是代码(从markhc偷来的部分!):
#include <regex>
#include <string>
#include <iostream>
using namespace std;
int main()
{
string regx = R"([0-9]{2}:[0-9]{2}:[0-9]{2})";
smatch matches;
// some test data
std::vector<std::string> inputs{
"00:00:00",
"99:99:99",
"1:00:00",
"AA:00:00",
"0B:0000",
"0B:00c00",
};
// Run tests and print result
for (auto& input : inputs) {
if (regex_search(input, matches, regex(regx)))
{
std::cout << input << " - Valid!" << std::endl;
}
else {
std::cout << input << " - Invalid!" << std::endl;
}
}
}
这也会产生输出:
00:00:00 - Valid!
99:99:99 - Valid!
1:00:00 - Invalid!
AA:00:00 - Invalid!
0B:0000 - Invalid!
0B:00c00 - Invalid!
正则表达式[0-9] {2}:[0-9] {2}:[0-9] {2}如下。
[0-9
]表示数字0-9
{2}
表示2次
:
表示您需要的分隔符
显示正则表达式的灵活性: ..例如,如果您想使用其他格式,例如000:0000,则只需将正则表达式更改为 [0-9] {3}:[0-9] {4},代码保持不变。