1

I have a program that reads a credit card number. I want to add in something that makes sure that 16 numbers are added in, no letters, and as many spaces as wanted (although they don't count towards numbers). Is there a function or set of functions to do this, or should I just make a bunch of while and if loops that use isdigit() and isalpha() that goes through the array one element at a time?

char cardNum[32];
cout << "Enter credit card number: ";
cin.getline(cardNum, 32); //Read in the entire line for the name
qwerty26
  • 61
  • 2
  • 7
  • 1
    Well you wouldn't need a bunch of while loops if you wanted to do it that way. One while loop would suffice. But there is a better to do what you want, look into [regular expressions](http://www.regular-expressions.info/). – Daniel Apr 25 '14 at 21:04

4 Answers4

2

There are numerous things you could do. One idea is to use std::find_if with a custom predicate. For example:

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

Then:

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

There is a case to be made for using std::string instead of a raw char array too:

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

Followed by:

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

That helps avoid the magic 32 and also allows inputs of any length.

dlf
  • 9,045
  • 4
  • 32
  • 58
1

I would use a regular expression to match this pattern. If you're using C++11, you can use the built in header: http://www.cplusplus.com/reference/regex/

Otherwise, take a look here for some alternative libraries you can use: C++: what regex library should I use?

Unfortunately, I'm not very good at regular expressions, but the following should match 16 numbers with spaces inbetween.

(\d[ ]*){16}

If you're looking for more info on regular expressions, here is a good cheat sheet I use often: http://regexlib.com/CheatSheet.aspx

I also like to test my expressions using this site: http://regexpal.com/

Community
  • 1
  • 1
E. Moffat
  • 3,165
  • 1
  • 21
  • 34
1

So something like this would be allowed?

"123  456  789 01     23456"

Use std::string and the free-standing std::getline function. It's better than the member function of the same name, because it doesn't force you to deal with pointers.

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

Then you have a string as in my example above in line. You could use std::find_if to verify that there are no illegal characters and std::count_if to make sure there are exactly 16 digits, but I think writing your own loop (not "bunch of loops") would yield more readable code here.

By the way, beware of isdigit! For historical reasons, you must cast its argument to unsigned char in order to use it safely.

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
0

There is an atoll function in the cstdlib. http://www.cplusplus.com/reference/cstdlib/atoll/

It converts character string input into a long long, which could store a 16 digit long credit card number, however this quits as soon as there's an non-numeric character in the input so

atoll("123456abc890")

would return 123456

If you want to check each character by character, you could just use atoi on each character then reassemble the string for each character that passes. http://www.cplusplus.com/reference/cstdlib/atoi/

hiddennin
  • 23
  • 4
  • `atoi` is broken. It will return 0 for both "0" and "x". – Christian Hackl Apr 25 '14 at 21:23
  • @ChristianHackl I guess you can't read documentations. "If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed and zero is returned." – hiddennin Apr 25 '14 at 21:57
  • "x" is the "the first sequence of non-whitespace characters" in the string. How does this contradict my comment? It supports it. You should really not offend other people like this. – Christian Hackl Apr 25 '14 at 22:05
  • And you should cite things you quote, by the way. Here is the source of your quote: http://www.cplusplus.com/reference/cstdlib/atoi/ – Christian Hackl Apr 25 '14 at 22:06