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
How to recover a single blank shot from a film camera
Basic power tool set for Home repair and simple projects
Object-oriented design implementation of an Elevator
You may find me... puzzling
Justifying Affordable Bespoke Spaceships
Do Battery Electrons Only Move If There is a Positive Terminal at the End of the Wire?
What is "dot" sign in •NO?
How useful is the GRE Exam?
Excel round 0.34 to 0.35
How do I become a better writer when I hate reading?
Probability Dilemma
How to use random to choose colors
Why swap space doesn't get filesystem check at boot time?
Fibonacci sequence and other metallic sequences emerged in the form of fractions
Should I email my professor to clear up a (possibly very irrelevant) awkward misunderstanding?
Is the infant mortality rate among African-American babies in Youngstown, Ohio greater than that of babies in Iran?
Root User Cannot Reset Another Users Password
How to make a villain when your PCs are villains?
Is this broken pipe the reason my freezer is not working? Can it be fixed?
How much steel armor can you wear and still be able to swim?
What is this plant I saw for sale at a Romanian farmer's market?
A medieval book with a redhead girl as a main character who allies with vampires and werewolves against scientific opposition
How did Frodo know where the Bree village was?
I have found ports on my Samsung smart tv running a display service. What can I do with it?
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;
$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
beginner c parsing checksum
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$
add a comment |
$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
beginner c parsing checksum
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$
1
$begingroup$
Have loops or functions been introduced yet?
$endgroup$
– pacmaninbw
9 hours ago
$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
9 hours ago
add a comment |
$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
beginner c parsing checksum
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
beginner c parsing checksum
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.
edited 7 hours ago
200_success
134k21166439
134k21166439
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 10 hours ago
Dan SuttonDan Sutton
313
313
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.
1
$begingroup$
Have loops or functions been introduced yet?
$endgroup$
– pacmaninbw
9 hours ago
$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
9 hours ago
add a comment |
1
$begingroup$
Have loops or functions been introduced yet?
$endgroup$
– pacmaninbw
9 hours ago
$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
9 hours ago
1
1
$begingroup$
Have loops or functions been introduced yet?
$endgroup$
– pacmaninbw
9 hours ago
$begingroup$
Have loops or functions been introduced yet?
$endgroup$
– pacmaninbw
9 hours ago
$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
9 hours ago
$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
9 hours ago
add a comment |
1 Answer
1
active
oldest
votes
$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. The first test to see if it is valid would then be to check if there are 15 or 16 numeric characters in the string, all valid credit card numbers have either 15 or 16 numbers in them (some AMEX cards have 15 numeric characters, all other credit cards have 16 numeric characters).
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.
$endgroup$
$begingroup$
Please can you review my update answer below?
$endgroup$
– Dan Sutton
3 hours ago
$begingroup$
There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
$endgroup$
– jcaron
38 mins ago
$begingroup$
@jcaron Are/were they in Europe or Asia?
$endgroup$
– pacmaninbw
30 mins ago
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
$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. The first test to see if it is valid would then be to check if there are 15 or 16 numeric characters in the string, all valid credit card numbers have either 15 or 16 numbers in them (some AMEX cards have 15 numeric characters, all other credit cards have 16 numeric characters).
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.
$endgroup$
$begingroup$
Please can you review my update answer below?
$endgroup$
– Dan Sutton
3 hours ago
$begingroup$
There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
$endgroup$
– jcaron
38 mins ago
$begingroup$
@jcaron Are/were they in Europe or Asia?
$endgroup$
– pacmaninbw
30 mins ago
add a comment |
$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. The first test to see if it is valid would then be to check if there are 15 or 16 numeric characters in the string, all valid credit card numbers have either 15 or 16 numbers in them (some AMEX cards have 15 numeric characters, all other credit cards have 16 numeric characters).
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.
$endgroup$
$begingroup$
Please can you review my update answer below?
$endgroup$
– Dan Sutton
3 hours ago
$begingroup$
There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
$endgroup$
– jcaron
38 mins ago
$begingroup$
@jcaron Are/were they in Europe or Asia?
$endgroup$
– pacmaninbw
30 mins ago
add a comment |
$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. The first test to see if it is valid would then be to check if there are 15 or 16 numeric characters in the string, all valid credit card numbers have either 15 or 16 numbers in them (some AMEX cards have 15 numeric characters, all other credit cards have 16 numeric characters).
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.
$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. The first test to see if it is valid would then be to check if there are 15 or 16 numeric characters in the string, all valid credit card numbers have either 15 or 16 numbers in them (some AMEX cards have 15 numeric characters, all other credit cards have 16 numeric characters).
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.
edited 6 hours ago
answered 6 hours ago
pacmaninbwpacmaninbw
6,59821639
6,59821639
$begingroup$
Please can you review my update answer below?
$endgroup$
– Dan Sutton
3 hours ago
$begingroup$
There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
$endgroup$
– jcaron
38 mins ago
$begingroup$
@jcaron Are/were they in Europe or Asia?
$endgroup$
– pacmaninbw
30 mins ago
add a comment |
$begingroup$
Please can you review my update answer below?
$endgroup$
– Dan Sutton
3 hours ago
$begingroup$
There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
$endgroup$
– jcaron
38 mins ago
$begingroup$
@jcaron Are/were they in Europe or Asia?
$endgroup$
– pacmaninbw
30 mins ago
$begingroup$
Please can you review my update answer below?
$endgroup$
– Dan Sutton
3 hours ago
$begingroup$
Please can you review my update answer below?
$endgroup$
– Dan Sutton
3 hours ago
$begingroup$
There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
$endgroup$
– jcaron
38 mins ago
$begingroup$
There are (or at least there was, not sure if it's still the case nowadays) cards with 19-digit PANs.
$endgroup$
– jcaron
38 mins ago
$begingroup$
@jcaron Are/were they in Europe or Asia?
$endgroup$
– pacmaninbw
30 mins ago
$begingroup$
@jcaron Are/were they in Europe or Asia?
$endgroup$
– pacmaninbw
30 mins ago
add a comment |
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.
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
1
$begingroup$
Have loops or functions been introduced yet?
$endgroup$
– pacmaninbw
9 hours ago
$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
9 hours ago