CS50 Problem set 1 Credit - can't find the logic error - c

When I enter a credit card number that should work it outputs "INVALID" when it should output the credit card brand. I believe something is going wrong in the validity function but i can't seem to figure out what. I've spent a couple hours trying to fix the problem but nothing has worked. It would be great if I could get some help, thanks so much!
This is my code:
#include <stdio.h>
#include <cs50.h>
bool validity(long long creditNum);
int find_length(long long n);
bool checksum(long long ccn);
void credit_card_num(long long ccn);
int main(void)
{
long long creditNum;
do
{
creditNum = get_long_long("Enter Card Number: ");
}
while(creditNum < 0);
if (validity(creditNum) == true)
credit_card_num(creditNum);
else
printf("INVALID\n");
}
bool validity(long long creditNum)
{
int length = find_length(creditNum);
if ((length == 13 || length == 15 || length == 16) && checksum(creditNum))
return true;
else
return false;
}
int find_length(long long n)
{
int length;
for (length = 0; n != 0; n/= 10)
length++;
return length;
}
bool checksum(long long ccn)
{
int sum = 0;
int digit;
for (int i = 0; ccn != 0; i++, ccn /= 10)
{
if (i % 2 == 0)
sum += ccn % 10;
else
digit = 2 * (ccn % 10);
sum += digit / 10 + digit % 10;
}
if ((sum % 10) == 0)
return true;
else
return false;
}
void credit_card_num(long long ccn)
{
if ((ccn >= 34e13 && ccn < 35e13) || (ccn >= 37e13 && ccn < 38e13))
printf("AMEX\n");
else if (ccn >= 51e14 && ccn < 56e14)
printf("MASTERCARD\n");
else if ((ccn >= 4e12 && ccn < 5e12) || (ccn >= 4e15 && ccn < 5e15))
printf("VISA\n");
else
printf("INVALID\n");
}

It looks like your error is in your checksum function; specifically, the for loop.
for (int i = 0; ccn != 0; i++, ccn /= 10)
{
if (i % 2 == 0)
sum += ccn % 10;
else
digit = 2 * (ccn % 10);
sum += digit / 10 + digit % 10;
}
should be
for (int i = 0; ccn != 0; i++, ccn /= 10)
{
if (i % 2 == 0){
sum += ccn % 10;
} else {
digit = 2 * (ccn % 10);
sum += digit / 10 + digit % 10;
}
}
There was incorrect nesting around your if-else statement. I tested with a couple numbers and they printed the correct output.

First of all, it would be great if you included the "get_long_long" function, so we could see how the input is taken.
Secondly, the digit variable inside the checksum function wasn't initialized, which caused some problems.
Lastly, from a brief look here, you kinda implemented the algorithm in a wrong way, I fixed it, please check that the result is working for you:
bool checksum(long long ccn)
{
int sum = 0;
int digit;
for (int i = 0; ccn != 0; i++, ccn /= 10)
{
digit = ccn % 10;
if (i % 2 != 0) {
digit *= 2;
if (digit > 9)
digit -= 9;
}
sum += digit;
}
if ((sum % 10) == 0)
return true;
else
return false;
}

Related

(CS50x Credit) expected "INVALID\n", not "VISA\n"

Task: the user enters the card number and needs to determine whether the card is valid and, if so, determine the type of card (Visa, MasterCard, American Express). We have [https://cs50.harvard.edu/college/2021/spring/psets/1/credit/#luhns-algorithm][Luhn's Algorithm] to determine the validation of card number.
Problem: sometimes programm identifies invalid card as Visa(for example: 4111111111111113, 4222222222223). I really don't know how to solve this problem( I've already seen other solutions of this CS50 Credit task, but since I'm a beginner, I want to know what's wrong exactly with this code. I would be grateful for any hints on this problem and the code as a whole. Appreciate your help!
#include <cs50.h>
#include <stdio.h>
#include <math.h>
int main(void)
{
long credit;
do
{
credit = get_long("Number of card:\n");
}
while (credit < 0);
long number = credit;
int digits;
for (digits = 0; number > 0; digits++)
{
number /= 10;
}
int checksum = 0;
int i;
for (i = 0; number > 0; i++, number /= 10)
{
if (i % 2 == 0)
{
checksum += (number % 10);
}
else
{
int n = (number % 10) * 2;
if (n > 9)
{
n = (n / 10) + (n % 10);
}
checksum += n;
}
}
checksum = checksum % 10;
if ((checksum == 0) && ((credit >= 34e13 && credit < 35e13) || (credit >= 37e13 && credit < 38e13)))
{
printf("AMEX\n");
}
else if ((checksum == 0) && (credit >= 51e14 && credit < 56e14))
{
printf("MASTERCARD\n");
}
else if ((checksum == 0) && ((credit >= 4e12 && credit < 5e12) || (credit >= 4e15 && credit < 5e15)))
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
Code changes number
for (digits = 0; number > 0; digits++) {
number /= 10;
}
int checksum = 0;
int i;
Consider the value of number after the above loop. Certainly 0. Next loop does not iterate.
for (i = 0; number > 0; i++, number /= 10)
Code needs to preserve number.

CS50 Credit Problem is skipping "else if" part

I am really stuck here. The programm gives right answer to invald credit card numbers but never say if its VISA, AMEX or MASTERCARD.
I need to post the complete code because I do not have so much experience wit the C language.
The checksum part in the end could also have been "bool" but I always got error messages with that.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
long long card;
int checksum = 0;
do
{
card = get_long_long("Number: ");
}while (card <= 0);
int count = 0;
while (card != 0) {
card /= 10; // n = n/10
++count;
}
if(count != 16 && count != 13 && count != 15){
printf("INVALID\n");
}
else if(checksum != 0){
printf("INVALID\n");
}
else if(card >= 34e13 || card >= 37e13){
printf("AMEX\n");
}
else if(card >= 51e14 || card >= 52e14 || card >= 53e14 || card >= 54e14 || card >= 55e15) {
printf("MASTERCARD\n");
}
else if(card >= 4e15 || card >=4e12) {
printf("VISA\n");
}
else {
printf("INVALID\n");
}
}
int checksum(long long card_nr)
{
int sum = 0;
for (int i=0;card_nr !=0; i++, card_nr/=10 )
{
if(i % 2 == 0)
sum += card_nr % 10;
else
{
int digit = 2 * (card_nr % 10);
sum += digit / 10 + digit % 10;
}
}
return (sum % 10) == 0;
}
There may be major issue or only some parenthesis, the programm is compiling. Thanks for any help.
There are many errors with the logic:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
long long card;
int checksum = 0;
do
{
card = get_long_long("Number: ");
}while (card <= 0);
int count = 0;
// ** In here you destroy card, so later card whill allways be 0
while (card != 0) {
card /= 10; // n = n/10
++count;
}
if(count != 16 && count != 13 && count != 15){
printf("INVALID\n");
}
else if(checksum != 0){
printf("INVALID\n");
}
//** here it is the same as if(card >= 34e13)
else if(card >= 34e13 || card >= 37e13){
printf("AMEX\n");
}
//** here it is the same as if(card >= 51e14)
//** also these values are already covered by last check
else if(card >= 51e14 || card >= 52e14 || card >= 53e14 || card >= 54e14 || card >= 55e15) {
printf("MASTERCARD\n");
}
//** here it is the same as if(card >= 4e15)
//** also these values are already covered by previous check
else if(card >= 4e15 || card >=4e12) {
printf("VISA\n");
}
else {
printf("INVALID\n");
}
}
int checksum(long long card_nr)
{
int sum = 0;
for (int i=0;card_nr !=0; i++, card_nr/=10 )
{
if(i % 2 == 0)
sum += card_nr % 10;
else
{
int digit = 2 * (card_nr % 10);
sum += digit / 10 + digit % 10;
}
}
return (sum % 10) == 0;
}```
After loop:
while (card != 0) {
card /= 10; // n = n/10
++count;
}
card = 0 and original card number is lost.
You can save original card number to another variable and then compare it.
Also it is better to use integer constants like 54LL << 14 instead of float 54e14

Why am I still getting the "expected identifier" error?

I'm new to programming (currently learning C and working alongside the cs50x course). I'm doing the Problem Set 1, Card. I'm supposed to make a program where you type a credit card number and it gives you the type of credit card (AMEX, VISA, etc). I need help with this error: "Error: expected identifier or '('"
Here is the code:
#include <stdio.h>
#include <cs50.h>
void print_credit_card_brand(long long ccn);
bool check_validity(long long credit_card_number);
int find_lenght(long long n);
bool checksum(long long ccn);
int main(void)
{
long long credit_card_number;
do
{
credit_card_number = get_long_long("Number: \n");
}
while (credit_card_number < 0);
if (check_validity(credit_card_number) == true)
print_credit_card_brand(credit_card_number);
else
printf ("INVALID\n");
}
bool check_validity(long long credit_card_number);
{
int len = find_lenght(credit_card_number);
return (len = 13 || len = 15 || len = 16) && checksum(credit_card_number);
}
int find_lenght(long long n);
{
int len;
for (int len = 0; n ! = 0; n/=10, len++)
return len;
}
bool checksum(long long ccn);
{
int sum = 0;
for (int i = 0; ccn!= 0; i++; ccn/= 10)
{
if(i % 2 == 0)
sum += ccn % 10;
else
{
int digit = 2 * (ccn % 10);
sum += digit / 10 + digit % 10;
}
return (sum % 10) == 0;
}
}
void print_credit_card_brand(long long ccn);
{
if ((ccn >= 34e13 && ccn < 32e13) || (ccn >= 37e13 && ccn < 38e13))
printf ("AMEX\n");
else if (ccn >= 51e14 && ccn < 56e14)
printf("MASTERCARD\n");
else if ((ccn >= 4e12 && ccn < 5e12) || (ccn >= 4e15 && ccn < 5e15))
printf("VISA\n");
else printf("INVALID\n");
}
Remove semicolon here. :D
bool check_validity(long long credit_card_number); <--------
{
int len = find_lenght(credit_card_number);
return (len = 13 || len = 15 || len = 16) && checksum(credit_card_number);
}
int find_lenght(long long n); <---------
.
.
.
You have some typos in your code:
Every function definition has an extra ; at the end, remove them all.
bool checksum(long long cc);
{ ^
//...
}
This:
return (len = 13 || len = 15 || len = 16) && checksum(credit_card_number);`
^ ^ ^
You probably want ==.
This:
for (int i = 0; ccn!= 0; i++; ccn/= 10)
^
You probably want:
for (int i = 0; ccn!= 0; i++, ccn/= 10)
This:
for (int len = 0; n ! = 0; n/=10, len++)
^
You'll want to remove that space and make it !=.

Regarding CS50 Problem Set 1 Credit - all inputs return "INVALID"

I first attempted the code myself, then tweaked it after watching Deliberate Think's video on Youtube. While my code can be compiled, all credit card number inputs return "INVALID" e.g. when using the testing AMEX number on PayPal (378282246310005), check50 says that: "identifies 378282246310005 as AMEX expected "AMEX\n", not "INVALID\n". I think there may be a problem under //implementing Luhn's algorithm.
Below is my code:
#include <stdio.h>
#include <cs50.h>
int find_length(long long ccn);
bool check_luhn(long long ccn);
bool check_validity(long long ccn);
void print_card_brand(long long ccn);
//prompt user for credit card number; if invalid prompts again
int main(void)
{
long long ccn;
do
{
ccn = get_long_long("Credit Card Number: ");
}
while (ccn < 0);
if (check_validity(ccn))
print_card_brand(ccn);
else
printf("INVALID\n");
}
//find the length of the credit card number
int find_length(long long ccn)
{
int length;
for (length = 0; ccn!= 0; ccn /=10);
length++;
return length;
}
//implementing Luhn's algorithm
bool check_luhn(long long ccn)
{
int sum = 0;
for (int i = 0; ccn != 0; i++, ccn /= 10)
{
if (i % 2 == 0)
sum += ccn % 10;
else
{
int digit = 2 * (ccn % 10);
sum += digit / 10 + digit % 10;
}
}
return (sum % 10) == 0;
}
//check length and Luhn's algorithm
bool check_validity(long long ccn)
{
int length = find_length(ccn);
return (length == 13 || length == 15 || length == 16) && check_luhn(ccn);
}
//print credit card brand
void print_card_brand(long long ccn)
{
if ( (ccn >= 34e13 && ccn < 35e13) || (ccn >= 37e13 && ccn < 38e13) )
printf("AMEX\n");
else if (ccn >= 51e14 && ccn < 56e14)
printf("MASTERCARD\n");
else if ( (ccn >= 4e12 && ccn < 5e12) || (ccn >= 4e15 && ccn < 5e15) )
printf("VISA\n");
else
printf("INVALID\n");
}
Thank you all in advance for your help, I've been stuck on this for so many days. Having never done coding before, I have no idea what went wrong.
You have a few bugs in there, one pointed out in the comments above is a rogue semicolon. Your implementation of luhn wasn't quite right so I've tried to fix it. I tried to fix this whilst making minimal changes. I didn't have access to CS50.h, so I addded stdbool and a dodgy scanf. I would undo those two changes.
#include <stdio.h>
#include <stdbool.h>
int find_length(long long ccn);
bool check_luhn(long long ccn);
bool check_validity(long long ccn);
void print_card_brand(long long ccn);
//prompt user for credit card number; if invalid prompts again
int main(void)
{
long long ccn;
do
{
scanf("Credit card number: %lld", &ccn);
}
while (ccn < 0);
if (check_validity(ccn))
print_card_brand(ccn);
else
printf("INVALID\n");
}
//find the length of the credit card number
int find_length(long long ccn)
{
int length;
for (length = 0; ccn!= 0; ccn /=10)
length++;
return length;
}
//implementing Luhn's algorithm
bool check_luhn(long long ccn)
{
int sum = 0;
long long temp_ccn = ccn;
int length = find_length(ccn);
for (int i = 1; i <= find_length(ccn); i++)
{
int rightDigit = temp_ccn % 10LL;
if (i % 2 == 0)
{
rightDigit = rightDigit * 2;
if (rightDigit > 9)
{
rightDigit -= 9;
}
}
sum += rightDigit;
temp_ccn /= 10LL;
}
return (sum % 10) == 0;
}
//check length and Luhn's algorithm
bool check_validity(long long ccn)
{
int length = find_length(ccn);
return (length == 13 || length == 15 || length == 16) && check_luhn(ccn);
}
//print credit card brand
void print_card_brand(long long ccn)
{
if ( (ccn >= 34e13 && ccn < 35e13) || (ccn >= 37e13 && ccn < 38e13) )
printf("AMEX\n");
else if (ccn >= 51e14 && ccn < 56e14)
printf("MASTERCARD\n");
else if ( (ccn >= 4e12 && ccn < 5e12) || (ccn >= 4e15 && ccn < 5e15) )
printf("VISA\n");
else
printf("INVALID\n");
}

Credit Card Number Verification

I am working on the credit problem of CS50. However, I am only printing INVALID no matter what card number I put in. May I ask what is the problem with my code? It seems that there is something wrong with the part to calculate the total sum.
#include <cs50.h>
#include <stdio.h>
#include <math.h>
int main(void)
{
// Get the card number
long num;
do
{
num = get_long("What is the card number?\n");
} while (num < 0);
long sum = 0, sum2 = 0, count = 0;
//Get the sum
for (long i = num; i > 0; i = i / 10)
{
sum += i % 10;
count++;
}
for (long i = num / 10; i > 0; i = i / 100)
{
sum2 += i % 10;
}
if ((sum + sum2) % 10 != 0)
{
printf("INVALID");
}
else
{
long digits = num / (10 * (count - 2));
if (count == 15 &&
(digits == 34 || digits == 37))
{
printf("AMERICAN EXPRESS");
}
else if (count == 16 && 51 <= digits <=55)
{
printf("MASTERCARD");
}
else if ((count == 16 || count == 13) && (digits / 10) == 4)
{
printf("VISA");
}
else
{
printf("INVALID");
}
}
}
This gives the sum of every digit.
for (long i = num; i > 0; i = i / 10)
{
sum += i % 10;
count++;
}
Review the problem set again, specifically the discussion of Luhn's Algorithm. There are two sums, however they are "mutually exclusive". If a digit is added to sum1 it will not be added to sum2. And versa vice. There is also a noticeable lack of *2 (times 2) anywhere in the code.
Perhaps you will find this walkthrough video helpful. Be warned: it is from an earlier version of the course and mentions the function get_long_long. That has been retired, use get_long as you have done here.

Resources