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

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 !=.

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: pset1: credit: Stuck, all cards entered invalid

Been working on this problem set for the past few hours and I thought I was doing pretty well, but when I ran it, doesn't really work as expected.
Kinda stuck at the moment, can anyone offer some insight?
EDIT
Sorry guys, I'll provide a little more insight on the problem because too little info is provided for it in my post. So basically I have to implement the Luhn's algorithm. According to Luhn’s algorithm, you can determine if a credit card number is (syntactically) valid as follows:
Multiply every other digit by 2, starting with the number’s second-to-last digit, and then add those products’ digits together.
Add the sum to the sum of the digits that weren’t multiplied by 2.
If the total’s last digit is 0 (or, put more formally, if the total modulo 10 is congruent to 0), the number is valid!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
printf("type a credit card number: ");
char ccnum[17];
fgets(ccnum, 17, stdin);
int ccnumber[15];
int n = strlen(ccnum);
for (int i = 0; i<16; i++)
{
ccnumber[i] = ccnum[i] -'0';
}
int ccnumber_m[7];
for (int i = 0; i < 16; i+=2)
{
ccnumber_m[i] = ccnumber[i]*2;
}
int sum = 0;
for (int i = 0; i < 8; i++)
{
if (ccnumber_m[i] > 9)
{
sum += (ccnumber_m[i] % 10) + 1;
}
else
{
sum += ccnumber_m[i];
}
printf("%d\n", sum);
}
for (int i = 1; i < 16; i+=2)
{
sum += ccnumber[i];
}
if (sum%10 == 0)
{
if ( (n == 15) && (ccnumber[0] == 34 || ccnumber[0] == 37))
{
printf("AMEX\n");
}
else if ((n == 16) && (ccnumber[0] == 51 || ccnumber[0] == 52 ||ccnumber[0] == 53 || ccnumber[0] == 54 || ccnumber[0] == 55))
{
printf("MASTERCARD\n");
}
else if ((n == 13 || n == 16) && ccnumber[0] == 4)
{
printf("VISA\n");
}
}
else
{
printf("INVALID\n");
}
}
I've added a printf to my sum variable to see where the program is failing and that's where things seem to be screwing up. Every time I run it, different values of sum appear?!
Thanks in advance.
Okay guys, found the solution. Yes I messed up most of my loops and the array ranges and the conditions were all over the place. Did some tweaks to my code overall and after a few more hours, the code works as expected. Here's the updated code.
Pretty sure the code could be more succinct and could be solved much faster. Will take a look at it tomorrow again in order to brainstorm more ideas and find ways to solve it faster.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
printf("type a credit card number: ");
char ccnum[17];
fgets(ccnum, 17, stdin);
int ccnumber[15];
int n = strlen(ccnum);
int counter = 0;
for (int i = 0; i < n; i++)
{
ccnumber[i] = ccnum[i] -'0';
if (ccnumber[i] >= 0)
{
counter ++;
}
}
int sum = 0;
if (counter == 16)
{
int ccnumber_m[7];
int index = 0;
for (int i = counter - 2; i > -1 ; i-=2, index++)
{
ccnumber_m[index] = ccnumber[i]*2;
}
for (int i = 0; i < 8; i++)
{
if (ccnumber_m[i] > 9)
{
sum += (ccnumber_m[i] % 10) + 1;
}
else
{
sum += ccnumber_m[i];
}
}
for (int i = 1; i < counter + 1; i+=2)
{
sum += ccnumber[i];
}
}
else if (counter == 15)
{
int ccnumber_m[6];
int index = 0;
for (int i = counter-2; i > 0; i-=2, index++)
{
ccnumber_m[index] = ccnumber[i]*2;
}
for (int i = 0; i < 7; i++)
{
if (ccnumber_m[i] > 9)
{
sum += (ccnumber_m[i] % 10) + 1;
}
else
{
sum += ccnumber_m[i];
}
}
for (int i = 0; i < counter + 1; i+=2)
{
sum += ccnumber[i];
}
}
else if(counter == 13)
{
int ccnumber_m[5];
int index = 0;
for (int i = counter-2; i > 0; i-=2, index++)
{
ccnumber_m[index] = ccnumber[i]*2;
}
for (int i = 0; i < 6; i++)
{
if (ccnumber_m[i] > 9)
{
sum += (ccnumber_m[i] % 10) + 1;
}
else
{
sum += ccnumber_m[i];
}
}
for (int i = 0; i < counter + 1; i+=2)
{
sum += ccnumber[i];
}
}
else
{
printf("INVALID\n");
return 0;
}
if (sum%10 == 0)
{
if ((counter == 15) && ((ccnumber[0] == 3 && ccnumber[1] == 4) || (ccnumber[0] == 3 && ccnumber[1] == 7)))
{
printf("AMEX\n");
}
else if ((counter == 16) && ((ccnumber[0] == 5 && ccnumber[1] == 1) || (ccnumber[0] == 5 && ccnumber[1] == 2) || (ccnumber[0] == 5 && ccnumber[1] == 3) || (ccnumber[0] == 5 && ccnumber[1] == 4) || (ccnumber[0] == 5 && ccnumber[1] == 5)))
{
printf("MASTERCARD\n");
}
else if ((counter == 13 || counter == 16) && (ccnumber[0] == 4))
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
return 0;
}
}
else
{
printf("INVALID\n");
return 0;
}
}

Getting unexpected results in CS50 readability problem

In solving this readability problem, I have been getting some weird unexpected results(expected Grade 16+, getting Grade 10 etc etc), I am not being able to figure out where the bug is or how can I solve it, please help me figure out the bug. The codes are as follows:
//includes
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
//global variables
int lc; //letter count
int wc; //word count
int sc; //sentence count
bool awc; //already word counted
double L; //average number of letters per 100 words
double S; //average number of sentences per 100 words
float index;
//function declaration
int count_letters(string x);
int count_words(string x);
int count_sentences(string x);
//main
int main(void)
{
string text = get_string("text : ");
count_letters(text);
printf("%i letters\n", lc);
count_words(text);
printf("%i words\n", wc);
count_sentences(text);
printf("%i sentences\n", sc);
L = lc / wc * 100.0f;
S = sc / wc * 100.0f;
index = (0.0588 * L) - (0.296 * S) - 15.8;
if(index < 1)
{
printf("Before Grade 1\n");
}
else if(index >= 16)
{
printf("Grade 16+\n");
}
else
{
printf("Grade %i\n", (int) round(index));
}
}
//functions
int count_letters(string x)
{
lc = 0;
for(int i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
lc += 1;
}
}
return lc;
}
int count_words(string x)
{
wc = 0;
awc = false;
for(int i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
if(awc == false)
{
wc += 1;
awc = true;
}
}
if(x[i] == ' ')
{
awc = false;
}
}
return wc;
}
int count_sentences(string x)
{
sc = 0;
for(int i = 0, n = strlen(x); i < n; i++)
{
if(x[i] == '.' || x[i] == '!' || x[i] == '?')
{
sc += 1;
}
}
return sc;
}
The number of letters, words and sentences from these functions are correct so far so I think the problem lies in the main section, probably something to do with the variable type of "L" and "S" or the index formulae, please help me figure out where the problem is. Thank you
here are some of the tests: sentences(expected results)
1.One fish. Two fish. Red fish. Blue fish. (Before Grade 1)
2.Harry Potter was a highly unusual boy in many ways. For one thing, he hated the summer holidays more than any other time of year. For another, he really wanted to do his homework, but was forced to do it in secret, in the dead of the night. And he also happened to be a wizard. (Grade 5)
3.A large class of computational problems involve the determination of properties of graphs, digraphs, integers, arrays of integers, finite families of finite sets, boolean formulas and elements of other countable domains. (Grade 16+)
L = lc / wc * 100.0f;
wrong
L = 100.0f * lc / wc;
right.
When both operands of / are integers, the result is integer as well, so 5/3 == 1.
the OPs code contains several problems, as discussed in the comments to the question.
The following proposed code:
corrects those problems exposed in the comments
cleanly compiles
strongly suggest all those 'global' variables be moved to inside the appropriate functions and when needed else where be passed as parameters.
and now, the proposed code:
//includes
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
//global variables
int lc; //letter count
int wc; //word count
int sc; //sentence count
bool awc; //already word counted
double L; //average number of letters per 100 words
double S; //average number of sentences per 100 words
double i;
//function declaration
int count_letters(string x);
int count_words(string x);
int count_sentences(string x);
//main
int main(void)
{
string text = get_string("text : ");
count_letters(text);
printf("%i letters\n", lc);
count_words(text);
printf("%i words\n", wc);
count_sentences(text);
printf("%i sentences\n", sc);
L = lc / wc * 100.0;
S = sc / wc * 100.0;
i = (0.0588 * L) - (0.296 * S) - 15.8;
if(i < 1.0)
{
printf("Before Grade 1\n");
}
else if(i >= 16.0)
{
printf("Grade 16+\n");
}
else
{
printf("Grade %i\n", (int) round(i));
}
}
//functions
int count_letters(string x)
{
lc = 0;
for( size_t i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
lc += 1;
}
}
return lc;
}
int count_words(string x)
{
wc = 0;
awc = false;
for( size_t i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
if(awc == false)
{
wc += 1;
awc = true;
}
}
if(x[i] == ' ')
{
awc = false;
}
}
return wc;
}
int count_sentences(string x)
{
sc = 0;
for( size_t i = 0, n = strlen(x); i < n; i++ )
{
if(x[i] == '.' || x[i] == '!' || x[i] == '?')
{
sc += 1;
}
}
return sc;
}

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

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;
}

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");
}

Resources