C++验证驾驶执照计划

C++ validating driving licence program

本文关键字:计划 驾驶执照 验证 C++      更新时间:2023-10-16

我已经用头撞了大约 2 个小时,所以决定对它进行第二双或更多的眼睛。 如果您能提供帮助,将不胜感激,如果答案是C ++或逻辑只是看不出为什么它不起作用。(我遇到的问题是运行时发生的"字符串下标超出范围")程序应该将 9 个字符放入一个字符串中,前 5 个字符应该是数字,后 4 个字符应该是字母。

cout<<"please enter in licence number :";
cin>>licence;
while(licence.length()!=9)
{
  cout<<"Sorry please re-enter licence should be 9 characters"<<endl<<"first 5 are numbers last 4 are Letters :";
  cout<<"please enter in licence number :";
  cin>>licence;
  system("CLS");
}
for(int i=0;i<=4;i++)
{
  for(int j=4;j<=9;j++)
  {
    while(!isdigit(licence[i])&&!isalpha(licence[j]))
    {
      cout<<"Sorry please re-enter licence should be 9 characters"<<endl<<"first 5 are numbers last 4 are Letters :";
      cout<<"please enter in licence number :";
      cin>>licence;
      system("CLS");
    }
  }
}

好的,这是我更新的功能,但仍然无法正常工作

bool islicensevalid(string license)
{
   if (license.length() != 9) 
   {
     cout<<"Not nine characters long "<<endl;
     return false;
   }
   for (unsigned short index = 0; index < 5; ++index)
   { 
      if(!isdigit(license[index]))
      {
        cout<<"first 5 characters aren't numbers"<<endl;
        return false;
      }
   }
   for (unsigned short index = 5; index < 9; ++index)
   {    
       if(!isalpha(license[index]))
       {
          cout<<"final 4 characters aren't letters"<<endl;
          return false;
       }
   }
   return true;
}

我再次更改了数字,但它要么有与以前相同的错误,要么说最后 4 位数字是字母

您应该将验证逻辑分解为单独的验证函数,因为您的输入和验证逻辑过于交织在一起,从而导致您的问题。 特别是,如果您发现许可证在验证循环中无效,则不会检查输入的新许可证长度是否正确,并且还会在中间重新启动验证。 那不好。

最好只是将关注点分开。 将验证逻辑放在一个函数中,并让输入循环调用它。 这将使一切更加清晰,更容易正确。

bool is_valid_license(const string &license)
{
    // Correct length?
    if (license.length() != 9)
        return false;
    // Are first five characters digits?
    for (int i = 0; i < 5; i++)
        if (!isdigit(license[i]))
             return false;
    // Are next four characters letters?
    for (int i = 5; i < 9; i++)
        if (!isalpha(license[i]))
             return false;
    // Valid license
    return true;
}

然后在输入代码中,您可以执行以下操作:

cout << "Please enter in licence number :";
cin >> licence;
while (! is_valid_license(license) )
{
    cout<<"Sorry please re-enter licence should be 9 characters"<<endl<<"first 5 are numbers last 4 are Letters :";
    cout<<"please enter in licence number :";
    cin>>licence;
}    

索引 9 超出范围,即内循环测试应该是您在最后一个循环的最后一次迭代中点击的j < 9

我还认为您需要在 5 而不是 4 处初始化j,因此您只测试 licence[5]licence[6]licence[7]licence[8]

目前,在外循环的最后一次迭代中,您正在测试"有效地执行此操作:

while(!isdigit(licence[4])&&!isalpha(licence[4]))

这应该总是评估到true.

所以总结一下,你应该有

for(int i=0;i<5;i++) //outer

for(int j=5;j<9;j++) //inner

外环更改实际上是我个人的偏好,我发现它比使用i <= MAX-1样式更常见。

编辑添加:我注意到一旦用户输入包含 9 个字符的单个字符串,您就会停止检查长度,没有什么可以阻止他们输入 9 个字符后跟 8 个字符的无效字符串,这也会导致问题。

在这里,除其他外,您正在阅读循环内部:

for(int i=0;i<=4;i++)
{
    for(int j=4;j<=9;j++)
    {
        while(!isdigit(licence[i])&&!isalpha(licence[j]))
        {
            cout<<"Sorry please re-enter licence should be 9 characters"<<endl<<"first 5 are numbers last 4 are Letters :";
            cout<<"please enter in licence number :";
            cin>>licence;
            system("CLS");
        }
    }
}

因此,如果第 4 位数字有错误,则从输入中读取。如果输入的许可证只有 3 位数字长会怎样?当您将从离开的位置继续迭代器时,while条件下的字符串访问将导致此崩溃。

你为什么要错综复杂的 for 循环?他们没有关系。

基本上,你应该做这样的事情:

std::string license;
do
{
  cout<<"please enter in licence number :";
  cin >> license;
}
while (!is_license_valid(license));

其中is_license_valid是执行验证的函数,它将打印错误消息并在第一个错误时返回:

bool is_license_valid(const std::string& license)
{
   if (license.length() != 9) 
   {
     // print error
     return false;
   }
   for (unsigned long index = 0; index < 4; ++index)
   { 
      // If not digit print error and return false
   }
   for (unsigned long index = 4; index < 9; ++index)
   { 
      // If not alpha print error and return false
   }
   // all tests passed !
   return true;
}