Как расставить петли для проверки номеров

У меня есть программа, которая читает номер кредитной карты. Я хочу добавить что-то, что гарантирует добавление 16 чисел, без букв и столько пробелов, сколько нужно (хотя они не учитываются в числах). Есть ли функция или набор функций для этого, или я должен просто сделать несколько циклов while и if, которые используют isdigit () и isalpha (), которые проходят через массив по одному элементу за раз?

char cardNum[32];
cout << "Enter credit card number: ";
cin.getline(cardNum, 32); //Read in the entire line for the name

1

Решение

Есть множество вещей, которые вы могли бы сделать. Одна идея состоит в том, чтобы использовать std::find_if с пользовательским предикатом. Например:

bool IsCharIllegal(char ch)
{
// return true or false based on whatever your exact requirements are
}

Затем:

auto itFound = std::find_if(cardNum, cardNum + 32, IsCharIllegal);
if(itFound != cardNum + 32)
// invalid character was entered!

Есть случай, который будет сделан для использования std::string вместо сырого char массив тоже:

std::string cardNum;
cout << "Enter credit card number: ";
std::cin >> cardNum;

С последующим:

auto itFound = std::find_if(cardNum.begin(), cardNum.end(), IsCharIllegal);
if(itFound != cardNum.end())
// invalid character was entered!

Это помогает избежать магии 32 а также позволяет вводить данные любой длины.

2

Другие решения

Я бы использовал регулярное выражение, чтобы соответствовать этому шаблону. Если вы используете C ++ 11, вы можете использовать встроенный заголовок: http://www.cplusplus.com/reference/regex/

В противном случае, посмотрите здесь некоторые альтернативные библиотеки, которые вы можете использовать: C ++: какую библиотеку регулярных выражений мне следует использовать?

К сожалению, я не очень хорош в регулярных выражениях, но следующее должно соответствовать 16 числам с пробелами между ними.

(\d[ ]*){16}

Если вы ищете дополнительную информацию о регулярных выражениях, вот хорошая шпаргалка, которую я часто использую: http://regexlib.com/CheatSheet.aspx

Мне также нравится проверять мои выражения, используя этот сайт: http://regexpal.com/

1

Так что-нибудь подобное будет разрешено?

"123  456  789 01     23456"

использование std::string и отдельно стоящая std::getline функция. Это лучше, чем функция-член с таким же именем, потому что она не заставляет вас иметь дело с указателями.

std::string line;
std::getline(std::cin, line);
if (!std::cin)
{
// catastrophic input failure
}

Тогда у вас есть строка, как в моем примере выше в line, Вы могли бы использовать std::find_if чтобы убедиться, что нет незаконных символов и std::count_if чтобы убедиться, что здесь точно 16 цифр, но я думаю, что написание вашего собственного цикла (а не «связки циклов») даст здесь более читаемый код.

Кстати, остерегаться isdigit! По историческим причинам, вы должны привести свой аргумент unsigned char для того, чтобы использовать его безопасно.

1

Есть atoll функция в cstdlib, http://www.cplusplus.com/reference/cstdlib/atoll/

Преобразует ввод строки символов в long long, который может хранить 16-значный номер кредитной карты, однако он завершается, как только на входе появляется нецифровый символ, поэтому

atoll("123456abc890")

вернется 123456

Если вы хотите проверить каждый символ за символом, вы можете просто использовать atoi на каждом символе затем заново собрать строку для каждого проходящего символа.
http://www.cplusplus.com/reference/cstdlib/atoi/

0