刚开始,请原谅此代码中缺少c ++约定和逻辑。我仍然试图绕过c ++的格式化语法..
通过这个较大的应用程序构建项目的这一小部分,我试图创建一个“数据验证”类型子例程,其中整数和字符串是主要测试用例,来自目标用户的输入。
问题是变量输入的每个字符都被迭代,即使'if语句'在'for循环'之外(或者在循环中的某些其他情况下)。
错误的一个例子是:
Enter a value:f1o2o3
Your value is a string
Your value is a integer
Your value is a string
Your value is a integer
Your value is a string
Your value is a integer
在第一个Your value is a string
和Your value is a integer
之后的额外线是不需要的。
我知道我可以只返回布尔变量letexists
或intexsits
,它们都被迭代而没有问题。然而,这个“字符迭代”问题在其他部分也是一个令人讨厌的问题,我似乎无法在任何地方找到明确的,可理解的解决方案。
我习惯使用python所以这个'在传递参数的同时遍历每个角色'对我来说是个新鲜事。
我已经尝试过多天查看它可能是什么了。两者:在线搜索并询问其他人(亲自向他们展示有问题的代码)关于“对每个角色的迭代”问题,然而,似乎没有人知道为什么会发生这种情况。
我已经通过在收到预期的数据值后打破while(true)
循环解决了这个问题,但是我知道这是非常糟糕的做法,因此想要弄清楚如何改进数据验证。
#include <iostream> // for std::cin, std::cout
#include <string> // for string datatype
#include <algorithm> // for std::find
#include <iterator> // for std::begin, std::end
using namespace std;
// If the 'cout's are changed to returning functions I will change this to a function itself (using int datacheck(...){...})
void datacheck(string &i) {
const char nums[] = { '0','1','2','3','4','5','6','7','8','9','\0' };
const char alph[] = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\0' };
for (char& c : i) {
bool intexists = find(begin(nums), end(nums), c) != end(nums);
bool letexists = find(begin(alph), end(alph), c) != end(alph);
if (letexists || (letexists && intexists))
cout << "Your value is a string" << endl;
// This will be changed for a return value
else if (!letexists && intexists)
cout << "Your value is a integer" << endl;
// This will be changed for a return value
else
cout << "Your value has an erogenous input (Special characters or non-letter/ number related stuff.";
}
}
int main(void) {
string checkedvalue;
cout << "Enter a value: ";
cin >> checkedvalue;
cin.clear();
cin.ignore(512, '\n');
datacheck(checkedvalue);
return 0;
}
我已经意识到这可能是因为每个字符都被单独发送到子例程中,但是,如果是这种情况,我仍然不确定如何解决这个问题。
结束...总的来说,一个解释为什么迭代发生以及如何修复的解释解决方案将非常感激。但是,如果可能的话,一般情况下,这种情况仍然会非常有用。
谢谢。
我不得不承认,我不理解你写的所有内容。我的理解是
问题是变量输入的每个字符都被迭代,即使'if语句'在'for循环'之外
那是错的!
for (char& c : i) {
bool intexists = find(begin(nums), end(nums), c) != end(nums);
bool letexists = find(begin(alph), end(alph), c) != end(alph);
if (letexists || (letexists && intexists))
cout << "Your value is a string" << endl;
// This will be changed for a return value
else if (!letexists && intexists)
cout << "Your value is a integer" << endl;
// This will be changed for a return value
else
cout << "Your value has an erogenous input (Special characters or non-letter/ number related stuff.";
}
以上所有都是“for循环”。简单来说,(循环)for循环的语法是
for (char& c : i) {
// body of the loop
}
如果你将{}
用于if,即使不需要和正确的意图,你的代码也会更加清晰和可读:
for (char& c : i) {
bool intexists = find(begin(nums), end(nums), c) != end(nums);
bool letexists = find(begin(alph), end(alph), c) != end(alph);
if (letexists || (letexists && intexists)) {
cout << "Your value is a string" << endl;
} else if (!letexists && intexists) {
cout << "Your value is a integer" << endl;
} else {
cout << "Your value has an erogenous input (Special characters or non-letter/ number related stuff.";
}
}
在C ++中,标准提供了不同的方法来检查字符串是否包含字母/数字值:
std::isalnum
std::isalpha
因此,您可以使用以下代码替换部分代码:
const all_numeric = std::all_of(std::begin(str), std::end(str), [](const auto c) {
return std::isalnum(c);
})
const all_alpha = std::all_of(std::begin(str), std::end(str), [](const auto c) {
return std::isalpha(c);
})
因此,要解决您的问题,您可以首先创建一个帮助函数,通过使用strtool
等标准函数或回收我们之后执行的操作来检查字符串是否为数字:
bool is_number(const std::string& s) {
return !s.empty() && std::find_if(s.begin(),
s.end(), [](char c) { return !std::isdigit(c); }) == s.end();
}
现在您知道字符串是否为数字,您可以检查您的字符串是否包含任何奇怪的字符,并将其丢弃。
void datacheck(string &i) {
const auto intexists = is_number(i);
if (intexists) {
// do whatever
return;
}
const all_alpha = std::all_of(std::begin(str), std::end(str), [](const auto c) {
return std::isalpha(c);
});
if (all_alpha) {
// do whatever
return;
}
}