为什么我的控制功能与它应该做的事情相反?

  • 本文关键字:控制 功能 c++ function struct
  • 更新时间 :
  • 英文 :

int control(int n, data a[], string cod){
for(int i = 0 ; i<n ; i++){
if(cod == a[i].code)
return i;
}
return -1;
}

大家好!这是我的控制功能。它用于检查用户输入的代码是否已经存在于结构中。这就是在";输入";功能:

void input(int &n, data a[]){
string code;
do{
cout<<"nInput the code: ";
cin>> code;
if((control(n,a,code))>0)
a[n].code=code;
else 
cout<<"nThe code you've input already exists. Please try again.";
}while((control(n,a,code)) == -1);
n++;
}

有两个问题:

  1. 每次我输入代码时,它都会告诉我它已经存在了,即使这是我第一次
  2. 它不会让我再试一次,即使代码已经存在

让我们从缩进代码开始,这样我们就可以更容易地理解它的作用:

int control(int n, data a[], string cod) {
for (int i = 0; i < n; i++)
{
if (cod == a[i].code)
return i;
}
return -1;
}

啊,所以它扫描一个数组,如果有字符串,则返回一个大于或等于0的值,如果没有,则返回-1。然后让我们考虑使用它的代码:

void input(int &n, data a[])
{
string code;
do
{
cout << "nInput the code: ";
cin >> code;
if ((control(n, a, code)) > 0)
a[n].code = code;
else
cout << "nThe code you've input already exists. Please try again.";
} while ((control(n, a, code)) == -1);
n++;
}

因此,如果返回值大于0,这将接受代码,否则将拒绝已存在的代码。这基本上是倒退的,但也不完全是这样。

我的建议是,首先定义一个枚举,为返回的值提供有意义的名称。这使得跟踪正在发生的事情变得更加容易:

enum { DUPLICATE, UNIQUE };
int control(int n, data a[], string cod) {
for (int i = 0; i < n; i++)
{
if (cod == a[i].code)
return DUPLICATE;
}
return UNIQUE;
}

现在,纠正我们的状况要容易得多,如果我们对它的反应不正确,也会更明显:

if (control(n, a, code) == UNIQUE)
a[n].code = code;
else
cout << "nThe code is a duplicate";

或者,如果你喜欢扭转这种情况,仍然很容易得到正确的答案:

if (control(n, a, code) == DUPLICATE)
cout << "nThe code is a duplicate";
else
a[n].code = code;

但特别是,如果你不小心把东西倒过来了,这将是非常明显的:

if (contro(n, a, code) == UNIQUE)
cout << "nThe code is a duplicate";

至少对我来说;独特的";在一行上;重复";就在下面,它似乎相当明显。

其他需要考虑的事项

  1. 我建议不要使用:

    using namespace std;
    

    在你的代码中,就像你现在所做的那样。这是一个坏习惯,现在可以节省一点打字,但从长远来看可能会导致相当大的悲伤。

  2. 我还会查找std::setstd::unordered_set,它们已经可以(更有效地(完成您使用data阵列所做的工作

  3. 如果/当您确实需要像C++中那样的数组时,您可能希望使用std::arraystd::vector,而不是内置的数组类型。它们更方便,并有助于防止相当多的错误。

  4. 对于一个试图显示代码是否已经在使用的函数,我会尝试想出一个比control更好的名称。control是一个通用的名称,如果不看它的内容,几乎不可能猜测它应该实现什么。一个好的函数名称可以很好地澄清使用它的代码,并显示您想要实现的代码:

    std::cin >> new_code;
    if (isDuplicate(new_code))
    std::cerr << "The code you entered is a duplicate. Please try againn";
    else
    codes.add(new_code);
    
do{
cout<<"nInput the code: ";
cin>> code;
if((control(n,a,code))>0)
a[n].code=code;
else cout<<"nThe code you've input already exists. Please try again.";
}while((control(n,a,code))==-1);

我看到这里至少有两个问题:

  • control在元素位于第一个位置时返回0,在条件中检查>0
  • 如果循环体成功地插入元件,则CCD_

我建议您使用std::find_if来检查元素是否已经存在。使用std::vector即:

#include <string>
#include <vector>
#include <algorithm>
struct data {
std::string code;
};
int main() {
std::vector<data> v;
std::string foo = "test";
auto it = std::find_if(v.begin(),v.end(),[foo](auto x){ return x.code == foo;});
bool found = (it == v.end());
}

如果您想要一个具有唯一条目的容器,也可以考虑使用std::set

最新更新