Credit card validation in CCredit card validationCredit card validator in PythonCredit card validation - Python 3.4UPenn CIS194: Credit Card Validation (Homework 1 Part 1 Tests)Simple Credit card validationDetermining whether a provided credit card number is valid according to Luhn’s algorithmCredit card validator in Python 3.7.1Implementation of Luhn credit card algorithmCredit card validator using Luhn AlgorithmOptimizing Luhn check digit algorithm

Does the posterior necessarily follow the same conditional dependence structure as the prior?

Is there any set of 2-6 notes that doesn't have a chord name?

Should my manager be aware of private LinkedIn approaches I receive? How to politely have this happen?

Impossible darts scores

90s (or earlier) cross-world fantasy book with a circular river and character-class tattoos

What reason would an alien civilization have for building a Dyson Sphere (or Swarm) if cheap Nuclear fusion is available?

Why do some professors with PhDs leave their professorships to teach high school?

Is this one of the engines from the 9/11 aircraft?

Fetch and print all properties of an object graph as string

Are there any vegetarian astronauts?

Why is the Turkish president's surname spelt in Russian as Эрдоган, with г?

Can the US president have someone sent to jail?

Going to get married soon, should I do it on Dec 31 or Jan 1?

Fedora boot screen shows both Fedora logo and Lenovo logo. Why and How?

How risky is real estate?

Animation advice please

Why does the numerical solution of an ODE move away from an unstable equilibrium?

Why is C++ initial allocation so much larger than C's?

Short and long term plans in a closed game in the Sicilian Defense

Isn't this a trivial corollary?

Analog is Obtuse!

Would a two-seat light aircaft with a landing speed of 20 knots and a top speed of 180 knots be technically possible?

In the Marvel universe, can a human have a baby with any non-human?

Is adding a new player (or players) a DM decision, or a group decision?



Credit card validation in C


Credit card validationCredit card validator in PythonCredit card validation - Python 3.4UPenn CIS194: Credit Card Validation (Homework 1 Part 1 Tests)Simple Credit card validationDetermining whether a provided credit card number is valid according to Luhn’s algorithmCredit card validator in Python 3.7.1Implementation of Luhn credit card algorithmCredit card validator using Luhn AlgorithmOptimizing Luhn check digit algorithm






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








10












$begingroup$


I am relatively new to C programming and I am currently working through the CS50 EDX course. The problem I have solved below is for week 1 (credit).



Any suggestions on how to improve this code to further my learning would be most appreciated. I feel like my solution is very clunky although it does the job!



#include <cs50.h>
#include <stdio.h>
#include <math.h>

int main(void)

long number = get_long("Number: ");

// get the individual intergers of number
// *2 odd digits

int i1 = ((number / 1000000000000000) % 10);
int t1 = i1 * 2;
int i2 = ((number / 100000000000000) % 10);
int i3 = ((number / 10000000000000) % 10);
int t3 = i3 * 2;
int i4 = ((number / 1000000000000) % 10);
int i5 = ((number / 100000000000) % 10);
int t5 = i5 * 2;
int i6 = ((number / 10000000000) % 10);
int i7 = ((number / 1000000000) % 10);
int t7 = i7 * 2;
int i8 = ((number / 100000000) % 10);
int i9 = ((number / 10000000) % 10);
int t9 = i9 * 2;
int i10 = ((number / 1000000) % 10);
int i11 = ((number / 100000) % 10);
int t11 = i11 * 2;
int i12 = ((number / 10000) % 10);
int i13 = ((number / 1000) % 10);
int t13 = i13 * 2;
int i14 = ((number / 100) % 10);
int i15 = ((number / 10) % 10);
int t15 = i15 * 2;
int i16 = (number % 10);

// Luhns Alg
// calculate sum of variable digits if > 9

if (t1>9)
t1 = t1 - 9;
if (t3>9)
t3 = t3 - 9;
if (t5>9)
t5 = t5 - 9;
if (t7>9)
t7 = t7 - 9;
if (t9>9)
t9 = t9 - 9;
if (t11>9)
t11 = t11 - 9;
if (t13>9)
t13 = t13 - 9;
if (t15>9)
t15 = t15 - 9;

// check lunghs algo = true (0)
// print card type

int sum = (t1+t3+t5+t7+t9+t11+t13+t15+i2+i4+i6+i8+i10+i12+i14+i16);
int check = (sum % 10);

if (check != 0)
printf("INVALIDn");
else
i2 == 5))

printf("MASTERCARDn");

else if (i1 == 4)

printf("VISAn");

else
printf("INVALIDn");




The code currently outputs the correct results below.



378282246310005 = AMEX

5555555555554444 = MASTERCARD

5105105105105100 = MASTERCARD

4111111111111111 = VISA

5673598276138003 = INVALID

4062901840 = INVALID










share|improve this question









New contributor



Dan Sutton is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$







  • 4




    $begingroup$
    Have loops or functions been introduced yet?
    $endgroup$
    – pacmaninbw
    Jun 15 at 13:10










  • $begingroup$
    Loops have and some basic functions like checking for a positive integer. I did think about looping through variables which I saw required vectors or arrays but haven't got to that yet so don't really understand.
    $endgroup$
    – Dan Sutton
    Jun 15 at 13:13

















10












$begingroup$


I am relatively new to C programming and I am currently working through the CS50 EDX course. The problem I have solved below is for week 1 (credit).



Any suggestions on how to improve this code to further my learning would be most appreciated. I feel like my solution is very clunky although it does the job!



#include <cs50.h>
#include <stdio.h>
#include <math.h>

int main(void)

long number = get_long("Number: ");

// get the individual intergers of number
// *2 odd digits

int i1 = ((number / 1000000000000000) % 10);
int t1 = i1 * 2;
int i2 = ((number / 100000000000000) % 10);
int i3 = ((number / 10000000000000) % 10);
int t3 = i3 * 2;
int i4 = ((number / 1000000000000) % 10);
int i5 = ((number / 100000000000) % 10);
int t5 = i5 * 2;
int i6 = ((number / 10000000000) % 10);
int i7 = ((number / 1000000000) % 10);
int t7 = i7 * 2;
int i8 = ((number / 100000000) % 10);
int i9 = ((number / 10000000) % 10);
int t9 = i9 * 2;
int i10 = ((number / 1000000) % 10);
int i11 = ((number / 100000) % 10);
int t11 = i11 * 2;
int i12 = ((number / 10000) % 10);
int i13 = ((number / 1000) % 10);
int t13 = i13 * 2;
int i14 = ((number / 100) % 10);
int i15 = ((number / 10) % 10);
int t15 = i15 * 2;
int i16 = (number % 10);

// Luhns Alg
// calculate sum of variable digits if > 9

if (t1>9)
t1 = t1 - 9;
if (t3>9)
t3 = t3 - 9;
if (t5>9)
t5 = t5 - 9;
if (t7>9)
t7 = t7 - 9;
if (t9>9)
t9 = t9 - 9;
if (t11>9)
t11 = t11 - 9;
if (t13>9)
t13 = t13 - 9;
if (t15>9)
t15 = t15 - 9;

// check lunghs algo = true (0)
// print card type

int sum = (t1+t3+t5+t7+t9+t11+t13+t15+i2+i4+i6+i8+i10+i12+i14+i16);
int check = (sum % 10);

if (check != 0)
printf("INVALIDn");
else
i2 == 5))

printf("MASTERCARDn");

else if (i1 == 4)

printf("VISAn");

else
printf("INVALIDn");




The code currently outputs the correct results below.



378282246310005 = AMEX

5555555555554444 = MASTERCARD

5105105105105100 = MASTERCARD

4111111111111111 = VISA

5673598276138003 = INVALID

4062901840 = INVALID










share|improve this question









New contributor



Dan Sutton is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$







  • 4




    $begingroup$
    Have loops or functions been introduced yet?
    $endgroup$
    – pacmaninbw
    Jun 15 at 13:10










  • $begingroup$
    Loops have and some basic functions like checking for a positive integer. I did think about looping through variables which I saw required vectors or arrays but haven't got to that yet so don't really understand.
    $endgroup$
    – Dan Sutton
    Jun 15 at 13:13













10












10








10


1



$begingroup$


I am relatively new to C programming and I am currently working through the CS50 EDX course. The problem I have solved below is for week 1 (credit).



Any suggestions on how to improve this code to further my learning would be most appreciated. I feel like my solution is very clunky although it does the job!



#include <cs50.h>
#include <stdio.h>
#include <math.h>

int main(void)

long number = get_long("Number: ");

// get the individual intergers of number
// *2 odd digits

int i1 = ((number / 1000000000000000) % 10);
int t1 = i1 * 2;
int i2 = ((number / 100000000000000) % 10);
int i3 = ((number / 10000000000000) % 10);
int t3 = i3 * 2;
int i4 = ((number / 1000000000000) % 10);
int i5 = ((number / 100000000000) % 10);
int t5 = i5 * 2;
int i6 = ((number / 10000000000) % 10);
int i7 = ((number / 1000000000) % 10);
int t7 = i7 * 2;
int i8 = ((number / 100000000) % 10);
int i9 = ((number / 10000000) % 10);
int t9 = i9 * 2;
int i10 = ((number / 1000000) % 10);
int i11 = ((number / 100000) % 10);
int t11 = i11 * 2;
int i12 = ((number / 10000) % 10);
int i13 = ((number / 1000) % 10);
int t13 = i13 * 2;
int i14 = ((number / 100) % 10);
int i15 = ((number / 10) % 10);
int t15 = i15 * 2;
int i16 = (number % 10);

// Luhns Alg
// calculate sum of variable digits if > 9

if (t1>9)
t1 = t1 - 9;
if (t3>9)
t3 = t3 - 9;
if (t5>9)
t5 = t5 - 9;
if (t7>9)
t7 = t7 - 9;
if (t9>9)
t9 = t9 - 9;
if (t11>9)
t11 = t11 - 9;
if (t13>9)
t13 = t13 - 9;
if (t15>9)
t15 = t15 - 9;

// check lunghs algo = true (0)
// print card type

int sum = (t1+t3+t5+t7+t9+t11+t13+t15+i2+i4+i6+i8+i10+i12+i14+i16);
int check = (sum % 10);

if (check != 0)
printf("INVALIDn");
else
i2 == 5))

printf("MASTERCARDn");

else if (i1 == 4)

printf("VISAn");

else
printf("INVALIDn");




The code currently outputs the correct results below.



378282246310005 = AMEX

5555555555554444 = MASTERCARD

5105105105105100 = MASTERCARD

4111111111111111 = VISA

5673598276138003 = INVALID

4062901840 = INVALID










share|improve this question









New contributor



Dan Sutton is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$




I am relatively new to C programming and I am currently working through the CS50 EDX course. The problem I have solved below is for week 1 (credit).



Any suggestions on how to improve this code to further my learning would be most appreciated. I feel like my solution is very clunky although it does the job!



#include <cs50.h>
#include <stdio.h>
#include <math.h>

int main(void)

long number = get_long("Number: ");

// get the individual intergers of number
// *2 odd digits

int i1 = ((number / 1000000000000000) % 10);
int t1 = i1 * 2;
int i2 = ((number / 100000000000000) % 10);
int i3 = ((number / 10000000000000) % 10);
int t3 = i3 * 2;
int i4 = ((number / 1000000000000) % 10);
int i5 = ((number / 100000000000) % 10);
int t5 = i5 * 2;
int i6 = ((number / 10000000000) % 10);
int i7 = ((number / 1000000000) % 10);
int t7 = i7 * 2;
int i8 = ((number / 100000000) % 10);
int i9 = ((number / 10000000) % 10);
int t9 = i9 * 2;
int i10 = ((number / 1000000) % 10);
int i11 = ((number / 100000) % 10);
int t11 = i11 * 2;
int i12 = ((number / 10000) % 10);
int i13 = ((number / 1000) % 10);
int t13 = i13 * 2;
int i14 = ((number / 100) % 10);
int i15 = ((number / 10) % 10);
int t15 = i15 * 2;
int i16 = (number % 10);

// Luhns Alg
// calculate sum of variable digits if > 9

if (t1>9)
t1 = t1 - 9;
if (t3>9)
t3 = t3 - 9;
if (t5>9)
t5 = t5 - 9;
if (t7>9)
t7 = t7 - 9;
if (t9>9)
t9 = t9 - 9;
if (t11>9)
t11 = t11 - 9;
if (t13>9)
t13 = t13 - 9;
if (t15>9)
t15 = t15 - 9;

// check lunghs algo = true (0)
// print card type

int sum = (t1+t3+t5+t7+t9+t11+t13+t15+i2+i4+i6+i8+i10+i12+i14+i16);
int check = (sum % 10);

if (check != 0)
printf("INVALIDn");
else
i2 == 5))

printf("MASTERCARDn");

else if (i1 == 4)

printf("VISAn");

else
printf("INVALIDn");




The code currently outputs the correct results below.



378282246310005 = AMEX

5555555555554444 = MASTERCARD

5105105105105100 = MASTERCARD

4111111111111111 = VISA

5673598276138003 = INVALID

4062901840 = INVALID







beginner c parsing checksum






share|improve this question









New contributor



Dan Sutton is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.










share|improve this question









New contributor



Dan Sutton is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








share|improve this question




share|improve this question








edited Jun 15 at 15:06









200_success

134k21 gold badges169 silver badges440 bronze badges




134k21 gold badges169 silver badges440 bronze badges






New contributor



Dan Sutton is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








asked Jun 15 at 12:06









Dan SuttonDan Sutton

514 bronze badges




514 bronze badges




New contributor



Dan Sutton is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




New contributor




Dan Sutton is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









  • 4




    $begingroup$
    Have loops or functions been introduced yet?
    $endgroup$
    – pacmaninbw
    Jun 15 at 13:10










  • $begingroup$
    Loops have and some basic functions like checking for a positive integer. I did think about looping through variables which I saw required vectors or arrays but haven't got to that yet so don't really understand.
    $endgroup$
    – Dan Sutton
    Jun 15 at 13:13












  • 4




    $begingroup$
    Have loops or functions been introduced yet?
    $endgroup$
    – pacmaninbw
    Jun 15 at 13:10










  • $begingroup$
    Loops have and some basic functions like checking for a positive integer. I did think about looping through variables which I saw required vectors or arrays but haven't got to that yet so don't really understand.
    $endgroup$
    – Dan Sutton
    Jun 15 at 13:13







4




4




$begingroup$
Have loops or functions been introduced yet?
$endgroup$
– pacmaninbw
Jun 15 at 13:10




$begingroup$
Have loops or functions been introduced yet?
$endgroup$
– pacmaninbw
Jun 15 at 13:10












$begingroup$
Loops have and some basic functions like checking for a positive integer. I did think about looping through variables which I saw required vectors or arrays but haven't got to that yet so don't really understand.
$endgroup$
– Dan Sutton
Jun 15 at 13:13




$begingroup$
Loops have and some basic functions like checking for a positive integer. I did think about looping through variables which I saw required vectors or arrays but haven't got to that yet so don't really understand.
$endgroup$
– Dan Sutton
Jun 15 at 13:13










1 Answer
1






active

oldest

votes


















9












$begingroup$

It might be better to treat the credit card number as a string. In the C programming language a string is a null terminated array of type char or character. This would remove all the division in the program to get each character. It would also allow the program to detect if any non-numeric characters were entered.



To get the actual numeric value of a character you would subtract '0' from the numeric character. For a single character this would always give you a value between zero and nine.



Variable Names

Having variables i1 through i16 is a very good indication that i should be an array, this is also true of t.



Having single character variable names is generally frowned upon except for loop control values. A single character really doesn't tell anyone reading or modifying the code what the variable really is or does. It isn't really clear in the program what i or t represents. While number is longer, it might be better if it was credit_card_number.



Basic Principles When Writing Code

One of the earliest principles all programmers learn is Don't Repeat Yourself, usually shortened to DRY code. Basically anytime you have code that repeats it would be better to put it into a loop or a function where the code is reused.



One example of repeating code from the question is :



 if (tN > 9)

tN = tN - 9;



This code can be made into a function:



int adjust_t_value(int tN)

if (tN > 9)

return tN - 9;

else

return tN;




If the variable t was an array, then code in the program could be reduced to



 for (int t_count = 0; t_count < N; t_count++)

t[t_count] = adjust_t_value(t[t_count]);



There is a second form of the if statement that could also make the code shorter, it is generally covered in the later part of any C programming course



 tN = (tN > 9)? tN - 9 : tN;


This single statement is equivalent to the function above.



A second example of repeating code is the division to reduce each digit in the credit card number to a single number, this could also be put into a loop. The divisor could be reduced in each iteration of the loop if the algorithm sticks with using numbers.



A second principle that should be taught early but is part of more complex programming is the Single Responsibility Principle which states that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated within the function, module or class. This reduces the size of functions which allows functions to be more readable, maintainable and easier to debug. This would mean breaking the main() function into two or three sub functions to reduce the complexity of main.



Use Vertical Spacing to Make the Code More Readable

The code in the question has the if (tN > 9) on only two lines, it might be more readable if it was 4 lines as shown above.






share|improve this answer











$endgroup$












  • $begingroup$
    Please can you review my update answer below?
    $endgroup$
    – Dan Sutton
    Jun 15 at 19:44










  • $begingroup$
    There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
    $endgroup$
    – jcaron
    Jun 15 at 22:27










  • $begingroup$
    @jcaron Are/were they in Europe or Asia?
    $endgroup$
    – pacmaninbw
    Jun 15 at 22:35






  • 1




    $begingroup$
    @pacmaninbw According to Wikipedia payment card numbers can range from 10 (formerly 8) to 19 digits, though in practice they actually range from 12 to 19. Examples include Maestro, China UnionPay, Diners Club, Discover, and JCB.
    $endgroup$
    – jcaron
    Jun 16 at 15:35






  • 1




    $begingroup$
    A string is absolutely the correct approach - after all, long (or even unsigned long) isn't necessarily large enough to represent decimals of the size required (9 digits are okay, but more than that is platform-dependent).
    $endgroup$
    – Toby Speight
    Jun 17 at 15:12













Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);






Dan Sutton is a new contributor. Be nice, and check out our Code of Conduct.









draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f222349%2fcredit-card-validation-in-c%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









9












$begingroup$

It might be better to treat the credit card number as a string. In the C programming language a string is a null terminated array of type char or character. This would remove all the division in the program to get each character. It would also allow the program to detect if any non-numeric characters were entered.



To get the actual numeric value of a character you would subtract '0' from the numeric character. For a single character this would always give you a value between zero and nine.



Variable Names

Having variables i1 through i16 is a very good indication that i should be an array, this is also true of t.



Having single character variable names is generally frowned upon except for loop control values. A single character really doesn't tell anyone reading or modifying the code what the variable really is or does. It isn't really clear in the program what i or t represents. While number is longer, it might be better if it was credit_card_number.



Basic Principles When Writing Code

One of the earliest principles all programmers learn is Don't Repeat Yourself, usually shortened to DRY code. Basically anytime you have code that repeats it would be better to put it into a loop or a function where the code is reused.



One example of repeating code from the question is :



 if (tN > 9)

tN = tN - 9;



This code can be made into a function:



int adjust_t_value(int tN)

if (tN > 9)

return tN - 9;

else

return tN;




If the variable t was an array, then code in the program could be reduced to



 for (int t_count = 0; t_count < N; t_count++)

t[t_count] = adjust_t_value(t[t_count]);



There is a second form of the if statement that could also make the code shorter, it is generally covered in the later part of any C programming course



 tN = (tN > 9)? tN - 9 : tN;


This single statement is equivalent to the function above.



A second example of repeating code is the division to reduce each digit in the credit card number to a single number, this could also be put into a loop. The divisor could be reduced in each iteration of the loop if the algorithm sticks with using numbers.



A second principle that should be taught early but is part of more complex programming is the Single Responsibility Principle which states that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated within the function, module or class. This reduces the size of functions which allows functions to be more readable, maintainable and easier to debug. This would mean breaking the main() function into two or three sub functions to reduce the complexity of main.



Use Vertical Spacing to Make the Code More Readable

The code in the question has the if (tN > 9) on only two lines, it might be more readable if it was 4 lines as shown above.






share|improve this answer











$endgroup$












  • $begingroup$
    Please can you review my update answer below?
    $endgroup$
    – Dan Sutton
    Jun 15 at 19:44










  • $begingroup$
    There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
    $endgroup$
    – jcaron
    Jun 15 at 22:27










  • $begingroup$
    @jcaron Are/were they in Europe or Asia?
    $endgroup$
    – pacmaninbw
    Jun 15 at 22:35






  • 1




    $begingroup$
    @pacmaninbw According to Wikipedia payment card numbers can range from 10 (formerly 8) to 19 digits, though in practice they actually range from 12 to 19. Examples include Maestro, China UnionPay, Diners Club, Discover, and JCB.
    $endgroup$
    – jcaron
    Jun 16 at 15:35






  • 1




    $begingroup$
    A string is absolutely the correct approach - after all, long (or even unsigned long) isn't necessarily large enough to represent decimals of the size required (9 digits are okay, but more than that is platform-dependent).
    $endgroup$
    – Toby Speight
    Jun 17 at 15:12















9












$begingroup$

It might be better to treat the credit card number as a string. In the C programming language a string is a null terminated array of type char or character. This would remove all the division in the program to get each character. It would also allow the program to detect if any non-numeric characters were entered.



To get the actual numeric value of a character you would subtract '0' from the numeric character. For a single character this would always give you a value between zero and nine.



Variable Names

Having variables i1 through i16 is a very good indication that i should be an array, this is also true of t.



Having single character variable names is generally frowned upon except for loop control values. A single character really doesn't tell anyone reading or modifying the code what the variable really is or does. It isn't really clear in the program what i or t represents. While number is longer, it might be better if it was credit_card_number.



Basic Principles When Writing Code

One of the earliest principles all programmers learn is Don't Repeat Yourself, usually shortened to DRY code. Basically anytime you have code that repeats it would be better to put it into a loop or a function where the code is reused.



One example of repeating code from the question is :



 if (tN > 9)

tN = tN - 9;



This code can be made into a function:



int adjust_t_value(int tN)

if (tN > 9)

return tN - 9;

else

return tN;




If the variable t was an array, then code in the program could be reduced to



 for (int t_count = 0; t_count < N; t_count++)

t[t_count] = adjust_t_value(t[t_count]);



There is a second form of the if statement that could also make the code shorter, it is generally covered in the later part of any C programming course



 tN = (tN > 9)? tN - 9 : tN;


This single statement is equivalent to the function above.



A second example of repeating code is the division to reduce each digit in the credit card number to a single number, this could also be put into a loop. The divisor could be reduced in each iteration of the loop if the algorithm sticks with using numbers.



A second principle that should be taught early but is part of more complex programming is the Single Responsibility Principle which states that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated within the function, module or class. This reduces the size of functions which allows functions to be more readable, maintainable and easier to debug. This would mean breaking the main() function into two or three sub functions to reduce the complexity of main.



Use Vertical Spacing to Make the Code More Readable

The code in the question has the if (tN > 9) on only two lines, it might be more readable if it was 4 lines as shown above.






share|improve this answer











$endgroup$












  • $begingroup$
    Please can you review my update answer below?
    $endgroup$
    – Dan Sutton
    Jun 15 at 19:44










  • $begingroup$
    There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
    $endgroup$
    – jcaron
    Jun 15 at 22:27










  • $begingroup$
    @jcaron Are/were they in Europe or Asia?
    $endgroup$
    – pacmaninbw
    Jun 15 at 22:35






  • 1




    $begingroup$
    @pacmaninbw According to Wikipedia payment card numbers can range from 10 (formerly 8) to 19 digits, though in practice they actually range from 12 to 19. Examples include Maestro, China UnionPay, Diners Club, Discover, and JCB.
    $endgroup$
    – jcaron
    Jun 16 at 15:35






  • 1




    $begingroup$
    A string is absolutely the correct approach - after all, long (or even unsigned long) isn't necessarily large enough to represent decimals of the size required (9 digits are okay, but more than that is platform-dependent).
    $endgroup$
    – Toby Speight
    Jun 17 at 15:12













9












9








9





$begingroup$

It might be better to treat the credit card number as a string. In the C programming language a string is a null terminated array of type char or character. This would remove all the division in the program to get each character. It would also allow the program to detect if any non-numeric characters were entered.



To get the actual numeric value of a character you would subtract '0' from the numeric character. For a single character this would always give you a value between zero and nine.



Variable Names

Having variables i1 through i16 is a very good indication that i should be an array, this is also true of t.



Having single character variable names is generally frowned upon except for loop control values. A single character really doesn't tell anyone reading or modifying the code what the variable really is or does. It isn't really clear in the program what i or t represents. While number is longer, it might be better if it was credit_card_number.



Basic Principles When Writing Code

One of the earliest principles all programmers learn is Don't Repeat Yourself, usually shortened to DRY code. Basically anytime you have code that repeats it would be better to put it into a loop or a function where the code is reused.



One example of repeating code from the question is :



 if (tN > 9)

tN = tN - 9;



This code can be made into a function:



int adjust_t_value(int tN)

if (tN > 9)

return tN - 9;

else

return tN;




If the variable t was an array, then code in the program could be reduced to



 for (int t_count = 0; t_count < N; t_count++)

t[t_count] = adjust_t_value(t[t_count]);



There is a second form of the if statement that could also make the code shorter, it is generally covered in the later part of any C programming course



 tN = (tN > 9)? tN - 9 : tN;


This single statement is equivalent to the function above.



A second example of repeating code is the division to reduce each digit in the credit card number to a single number, this could also be put into a loop. The divisor could be reduced in each iteration of the loop if the algorithm sticks with using numbers.



A second principle that should be taught early but is part of more complex programming is the Single Responsibility Principle which states that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated within the function, module or class. This reduces the size of functions which allows functions to be more readable, maintainable and easier to debug. This would mean breaking the main() function into two or three sub functions to reduce the complexity of main.



Use Vertical Spacing to Make the Code More Readable

The code in the question has the if (tN > 9) on only two lines, it might be more readable if it was 4 lines as shown above.






share|improve this answer











$endgroup$



It might be better to treat the credit card number as a string. In the C programming language a string is a null terminated array of type char or character. This would remove all the division in the program to get each character. It would also allow the program to detect if any non-numeric characters were entered.



To get the actual numeric value of a character you would subtract '0' from the numeric character. For a single character this would always give you a value between zero and nine.



Variable Names

Having variables i1 through i16 is a very good indication that i should be an array, this is also true of t.



Having single character variable names is generally frowned upon except for loop control values. A single character really doesn't tell anyone reading or modifying the code what the variable really is or does. It isn't really clear in the program what i or t represents. While number is longer, it might be better if it was credit_card_number.



Basic Principles When Writing Code

One of the earliest principles all programmers learn is Don't Repeat Yourself, usually shortened to DRY code. Basically anytime you have code that repeats it would be better to put it into a loop or a function where the code is reused.



One example of repeating code from the question is :



 if (tN > 9)

tN = tN - 9;



This code can be made into a function:



int adjust_t_value(int tN)

if (tN > 9)

return tN - 9;

else

return tN;




If the variable t was an array, then code in the program could be reduced to



 for (int t_count = 0; t_count < N; t_count++)

t[t_count] = adjust_t_value(t[t_count]);



There is a second form of the if statement that could also make the code shorter, it is generally covered in the later part of any C programming course



 tN = (tN > 9)? tN - 9 : tN;


This single statement is equivalent to the function above.



A second example of repeating code is the division to reduce each digit in the credit card number to a single number, this could also be put into a loop. The divisor could be reduced in each iteration of the loop if the algorithm sticks with using numbers.



A second principle that should be taught early but is part of more complex programming is the Single Responsibility Principle which states that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated within the function, module or class. This reduces the size of functions which allows functions to be more readable, maintainable and easier to debug. This would mean breaking the main() function into two or three sub functions to reduce the complexity of main.



Use Vertical Spacing to Make the Code More Readable

The code in the question has the if (tN > 9) on only two lines, it might be more readable if it was 4 lines as shown above.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jun 17 at 15:12









Toby Speight

29.9k7 gold badges45 silver badges129 bronze badges




29.9k7 gold badges45 silver badges129 bronze badges










answered Jun 15 at 16:20









pacmaninbwpacmaninbw

6,7232 gold badges17 silver badges39 bronze badges




6,7232 gold badges17 silver badges39 bronze badges











  • $begingroup$
    Please can you review my update answer below?
    $endgroup$
    – Dan Sutton
    Jun 15 at 19:44










  • $begingroup$
    There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
    $endgroup$
    – jcaron
    Jun 15 at 22:27










  • $begingroup$
    @jcaron Are/were they in Europe or Asia?
    $endgroup$
    – pacmaninbw
    Jun 15 at 22:35






  • 1




    $begingroup$
    @pacmaninbw According to Wikipedia payment card numbers can range from 10 (formerly 8) to 19 digits, though in practice they actually range from 12 to 19. Examples include Maestro, China UnionPay, Diners Club, Discover, and JCB.
    $endgroup$
    – jcaron
    Jun 16 at 15:35






  • 1




    $begingroup$
    A string is absolutely the correct approach - after all, long (or even unsigned long) isn't necessarily large enough to represent decimals of the size required (9 digits are okay, but more than that is platform-dependent).
    $endgroup$
    – Toby Speight
    Jun 17 at 15:12
















  • $begingroup$
    Please can you review my update answer below?
    $endgroup$
    – Dan Sutton
    Jun 15 at 19:44










  • $begingroup$
    There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
    $endgroup$
    – jcaron
    Jun 15 at 22:27










  • $begingroup$
    @jcaron Are/were they in Europe or Asia?
    $endgroup$
    – pacmaninbw
    Jun 15 at 22:35






  • 1




    $begingroup$
    @pacmaninbw According to Wikipedia payment card numbers can range from 10 (formerly 8) to 19 digits, though in practice they actually range from 12 to 19. Examples include Maestro, China UnionPay, Diners Club, Discover, and JCB.
    $endgroup$
    – jcaron
    Jun 16 at 15:35






  • 1




    $begingroup$
    A string is absolutely the correct approach - after all, long (or even unsigned long) isn't necessarily large enough to represent decimals of the size required (9 digits are okay, but more than that is platform-dependent).
    $endgroup$
    – Toby Speight
    Jun 17 at 15:12















$begingroup$
Please can you review my update answer below?
$endgroup$
– Dan Sutton
Jun 15 at 19:44




$begingroup$
Please can you review my update answer below?
$endgroup$
– Dan Sutton
Jun 15 at 19:44












$begingroup$
There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
$endgroup$
– jcaron
Jun 15 at 22:27




$begingroup$
There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
$endgroup$
– jcaron
Jun 15 at 22:27












$begingroup$
@jcaron Are/were they in Europe or Asia?
$endgroup$
– pacmaninbw
Jun 15 at 22:35




$begingroup$
@jcaron Are/were they in Europe or Asia?
$endgroup$
– pacmaninbw
Jun 15 at 22:35




1




1




$begingroup$
@pacmaninbw According to Wikipedia payment card numbers can range from 10 (formerly 8) to 19 digits, though in practice they actually range from 12 to 19. Examples include Maestro, China UnionPay, Diners Club, Discover, and JCB.
$endgroup$
– jcaron
Jun 16 at 15:35




$begingroup$
@pacmaninbw According to Wikipedia payment card numbers can range from 10 (formerly 8) to 19 digits, though in practice they actually range from 12 to 19. Examples include Maestro, China UnionPay, Diners Club, Discover, and JCB.
$endgroup$
– jcaron
Jun 16 at 15:35




1




1




$begingroup$
A string is absolutely the correct approach - after all, long (or even unsigned long) isn't necessarily large enough to represent decimals of the size required (9 digits are okay, but more than that is platform-dependent).
$endgroup$
– Toby Speight
Jun 17 at 15:12




$begingroup$
A string is absolutely the correct approach - after all, long (or even unsigned long) isn't necessarily large enough to represent decimals of the size required (9 digits are okay, but more than that is platform-dependent).
$endgroup$
– Toby Speight
Jun 17 at 15:12










Dan Sutton is a new contributor. Be nice, and check out our Code of Conduct.









draft saved

draft discarded


















Dan Sutton is a new contributor. Be nice, and check out our Code of Conduct.












Dan Sutton is a new contributor. Be nice, and check out our Code of Conduct.











Dan Sutton is a new contributor. Be nice, and check out our Code of Conduct.














Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f222349%2fcredit-card-validation-in-c%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

Circuit construction for execution of conditional statements using least significant bitHow are two different registers being used as “control”?How exactly is the stated composite state of the two registers being produced using the $R_zz$ controlled rotations?Efficiently performing controlled rotations in HHLWould this quantum algorithm implementation work?How to prepare a superposed states of odd integers from $1$ to $sqrtN$?Why is this implementation of the order finding algorithm not working?Circuit construction for Hamiltonian simulationHow can I invert the least significant bit of a certain term of a superposed state?Implementing an oracleImplementing a controlled sum operation

Magento 2 “No Payment Methods” in Admin New OrderHow to integrate Paypal Express Checkout with the Magento APIMagento 1.5 - Sales > Order > edit order and shipping methods disappearAuto Invoice Check/Money Order Payment methodAdd more simple payment methods?Shipping methods not showingWhat should I do to change payment methods if changing the configuration has no effects?1.9 - No Payment Methods showing upMy Payment Methods not Showing for downloadable/virtual product when checkout?Magento2 API to access internal payment methodHow to call an existing payment methods in the registration form?