fork download
  1. /**************************************************
  2.  * new_credit.c *
  3.  * *
  4.  * CS50 *
  5.  * *
  6.  * Prompts the user for a credit card number, *
  7.  * *
  8.  * determines the type of the card *
  9.  * *
  10.  * (Visa, American Express, Mastercard) *
  11.  * *
  12.  * and tests its validity. *
  13.  *************************************************/
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <stdbool.h>
  18. #include <math.h>
  19.  
  20. #define BUFFER_SIZE 256
  21.  
  22. char* get_input(void);
  23. bool is_number(char *alleged_number);
  24. long long int* string_to_long_long(char *string);
  25. int count_digits(long long int number);
  26. void credit_card_type(long long int credit_card_number, int credit_card_number_length);
  27. bool is_credit_card_valid(long long int credit_card_number, int credit_card_number_length);
  28.  
  29. int
  30. main(void)
  31. {
  32. long long int *credit_card_number = string_to_long_long(get_input());
  33. int credit_card_number_length = count_digits(*credit_card_number);
  34.  
  35. credit_card_type(*credit_card_number, credit_card_number_length);
  36.  
  37. return 0;
  38. }
  39.  
  40. /*
  41.  * Gets a credit card number from the user.
  42.  */
  43. char*
  44. get_input(void)
  45. {
  46. char temp_credit_card_number[BUFFER_SIZE];
  47.  
  48. // prompt the user for a credit card number
  49. printf("Enter a credit card number: ");
  50. // copy from standard input to temp_credit_card_number[]
  51. while (fgets(temp_credit_card_number, BUFFER_SIZE, stdin) != NULL) {
  52. // add the trailling '\0' at the end of the string
  53. for (int i = 0; i < BUFFER_SIZE; i++) {
  54. if (temp_credit_card_number[i] == '\n') {
  55. temp_credit_card_number[i] = '\0';
  56. break;
  57. }
  58. }
  59. // check user input
  60. if ( !(is_number(temp_credit_card_number)) ) {
  61. printf("Retry: ");
  62. } else {
  63. break;
  64. }
  65. }
  66.  
  67. // get_input() returns a pointer
  68. char *value = temp_credit_card_number;
  69.  
  70. return value;
  71. }
  72.  
  73. /*
  74.  * Checks that the user input is a number.
  75.  */
  76. bool
  77. is_number(char *alleged_number)
  78. {
  79. long long int number;
  80. char *invalid;
  81.  
  82. number = strtoll(alleged_number, &invalid, 10);
  83. if (*invalid != '\0') {
  84. return false;
  85. }
  86.  
  87. return true;
  88. }
  89.  
  90. /*
  91.  * Converts a string to a long long integer.
  92.  */
  93. long long int*
  94. string_to_long_long(char *string)
  95. {
  96. char *invalid;
  97. long long int number = strtoll(string, &invalid, 10);
  98. long long int *value = &number;
  99.  
  100. return value;
  101. }
  102.  
  103. /*
  104.  * Counts the number of digits of a number.
  105.  */
  106. int
  107. count_digits(long long int number)
  108. {
  109. int i;
  110.  
  111. for (i = 0; number != 0 ; i++) {
  112. number /= 10;
  113. }
  114.  
  115. return i;
  116. }
  117.  
  118. /*
  119.  * Determines the type of a credit card,
  120.  * (Visa, American Express, Mastercard)
  121.  */
  122. void
  123. credit_card_type(long long int credit_card_number, int credit_card_number_length)
  124. {
  125. // these variables store the first or two first digits of a credit card number.
  126. int visa_first_digit_13 = (credit_card_number / pow(10, 12));
  127. int visa_first_digit_16 = (credit_card_number / pow(10, 15));
  128. int amex_two_first_digits = (credit_card_number / pow(10, 13));
  129. int mastercard_two_first_digits = (credit_card_number / pow(10, 14));
  130.  
  131. // determines the possible type of a card then test its validity
  132. switch (credit_card_number_length) {
  133. case 13:
  134. // VISA ?
  135. if (visa_first_digit_13 == 4) {
  136. if (is_credit_card_valid(credit_card_number, credit_card_number_length))
  137. printf("VISA\n");
  138. } else {
  139. printf("INVALID\n");
  140. }
  141. break;
  142.  
  143. case 15:
  144. // AMEX ?
  145. if ((amex_two_first_digits == 34) || (amex_two_first_digits == 37)) {
  146. if (is_credit_card_valid(credit_card_number, credit_card_number_length))
  147. printf("AMEX\n");
  148. } else {
  149. printf("INVALID\n");
  150. }
  151. break;
  152.  
  153. case 16:
  154. // VISA ?
  155. if (visa_first_digit_16 == 4) {
  156. if (is_credit_card_valid(credit_card_number, credit_card_number_length))
  157. printf("VISA\n");
  158. // MASTERCARD ?
  159. } else if ((mastercard_two_first_digits == 51) ||
  160. (mastercard_two_first_digits == 52) ||
  161. (mastercard_two_first_digits == 53) ||
  162. (mastercard_two_first_digits == 54) ||
  163. (mastercard_two_first_digits == 55)
  164. ) {
  165. if (is_credit_card_valid(credit_card_number, credit_card_number_length))
  166. printf("MASTERCARD\n");
  167. } else {
  168. printf("INVALID\n");
  169. }
  170. break;
  171.  
  172. default:
  173. printf("INVALID\n");
  174. }
  175.  
  176. return;
  177. }
  178.  
  179. /*
  180.  * Tets the syntactic validity of a credit card number,
  181.  * (Peter Luhn's algoritm).
  182.  */
  183. bool
  184. is_credit_card_valid(long long int credit_card_number, int credit_card_number_length)
  185. {
  186. long long int every_other_digit;
  187. int sum_products_digits = 0;
  188.  
  189. /* isolate every other digits starting with the number's second-to-last digit,
  190.   multiply it by 2, and then add those products' digits together */
  191. for (int i = credit_card_number_length - 2; i > -1; i -= 2 ) {
  192. every_other_digit = ((long long int) (credit_card_number / pow(10, i))) % 10;
  193. sum_products_digits += ((every_other_digit * 2) / 10) + ((every_other_digit * 2) % 10);
  194. }
  195.  
  196. long long int left_out_digit;
  197. int sum_left_out_digits = 0;
  198.  
  199. // isolate the digits which weren't multiplied by 2, and then add these digits together
  200. for (int i = credit_card_number_length - 1; i > -1; i -= 2) {
  201. left_out_digit = ((long long int) (credit_card_number / pow(10, i))) % 10;
  202. sum_left_out_digits += left_out_digit;
  203. }
  204.  
  205. int final_sum = sum_products_digits + sum_left_out_digits;
  206.  
  207. // test weather the last digit of "final_sum" is 0 or not
  208. if (final_sum % 10 == 0) {
  209. return true;
  210. } else {
  211. return false;
  212. }
  213. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.c: In function ‘get_input’:
prog.c:53: error: ‘for’ loop initial declaration used outside C99 mode
prog.c: In function ‘is_credit_card_valid’:
prog.c:191: error: ‘for’ loop initial declaration used outside C99 mode
prog.c:200: error: redefinition of ‘i’
prog.c:191: error: previous definition of ‘i’ was here
prog.c:200: error: ‘for’ loop initial declaration used outside C99 mode
stdout
Standard output is empty