如何在没有原因(有输入)的情况下修复迭代;在 c++ 中?

How to fix iteration without a cause (with an input); in c++?

本文关键字:迭代 c++ 情况下 输入      更新时间:2023-10-16

只是在开始,请原谅此代码中缺少 c++ 约定和逻辑。我仍在尝试绕过 c++ 的格式化语法。

对于一个更大的应用程序构建项目的一小部分,我正在尝试创建一个"数据验证"类型的子例程,其中整数和字符串是主要的测试用例,输入来自预期用户。

问题是变量输入的每个字符都被迭代,即使"if 语句"在"for 循环"之外(或者在其他一些情况下 while 循环)。

该错误的一个例子是:

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是不需要的。

我知道我可以只返回布尔变量letexistsintexsits,它们都可以毫无问题地迭代。 然而,这个"字符迭代"问题在其他部分也令人讨厌,我似乎无法在任何地方找到确定的、可以理解的解决方法。

我习惯使用 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','' };
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','' };
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;
}
}