Я бил головой об этом около двух часов, поэтому решил получить второй или более набор глаз. если вы можете помочь, было бы очень полезно не беспокоиться, если ответ в 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
который вы нажимаете на последнюю итерацию последнего цикла.
Я также думаю, что вам нужно инициализировать j
в 5 вместо 4, поэтому вы проверяете только 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 символов, что также вызовет проблемы.
Здесь, между прочим, вы читаете INSIDE цикл:
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
приведет к сбою.
И почему вы замыслили циклы? Они не имеют никакого отношения.
В принципе, вы должны сделать что-то вроде:
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;
}
unsigned long
избыточное число unsigned long
для числа в диапазоне 0,9?