У меня есть программа, которая читает номер кредитной карты. Я хочу добавить что-то, что гарантирует добавление 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
Есть множество вещей, которые вы могли бы сделать. Одна идея состоит в том, чтобы использовать 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
а также позволяет вводить данные любой длины.
Я бы использовал регулярное выражение, чтобы соответствовать этому шаблону. Если вы используете C ++ 11, вы можете использовать встроенный заголовок: http://www.cplusplus.com/reference/regex/
В противном случае, посмотрите здесь некоторые альтернативные библиотеки, которые вы можете использовать: C ++: какую библиотеку регулярных выражений мне следует использовать?
К сожалению, я не очень хорош в регулярных выражениях, но следующее должно соответствовать 16 числам с пробелами между ними.
(\d[ ]*){16}
Если вы ищете дополнительную информацию о регулярных выражениях, вот хорошая шпаргалка, которую я часто использую: http://regexlib.com/CheatSheet.aspx
Мне также нравится проверять мои выражения, используя этот сайт: http://regexpal.com/
Так что-нибудь подобное будет разрешено?
"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
для того, чтобы использовать его безопасно.
Есть atoll
функция в cstdlib
, http://www.cplusplus.com/reference/cstdlib/atoll/
Преобразует ввод строки символов в long long
, который может хранить 16-значный номер кредитной карты, однако он завершается, как только на входе появляется нецифровый символ, поэтому
atoll("123456abc890")
вернется 123456
Если вы хотите проверить каждый символ за символом, вы можете просто использовать atoi
на каждом символе затем заново собрать строку для каждого проходящего символа.
http://www.cplusplus.com/reference/cstdlib/atoi/