I ran compile this:
char get_credit_card_status(long long credit_card_number, char Luhn_validity)//, char credit_card_status)
{
char credit_card_status = 0;
if (((credit_card_number < 350000000000000) && (340000000000000 <=credit_card_number)) && (Luhn_validity=1))
{
credit_card_status = 1;
printf("1 test\n");
}
else if ((5100000000000000<= credit_card_number) && (credit_card_number < 5500000000000000) && Luhn_validity)
{
credit_card_status = 2;
printf("2 test\n");
}
else if ((((4000000000000<= credit_card_number)&&(credit_card_number<5000000000000)) || ((4000000000000000<=credit_card_number)&&(credit_card_number<5000000000000000))) && Luhn_validity)
{
credit_card_status= 3;
printf("3 test\n");
}
return credit_card_status;
}
int length_ccn(long long credit_card_number)
{
int length = 0;
while (credit_card_number > 0)
{
length++;
credit_card_number /= 10 ;
}
return length;
}
char Luhn_check(long long credit_card_number)
{
int total_even_numbers = 0;
int total_odd_numbers = 0;
int even_number = 0;
int odd_number = 0;
int Luhn_sum = 0;
char Luhn_validity = 0;
long long check_digit_basis = credit_card_number;
for(int i =1 ; check_digit_basis > 0 ; i++)
{
if ((i % 2) > 0)
{
odd_number = (check_digit_basis % 10);
total_odd_numbers = total_odd_numbers + odd_number;
}
else
{
even_number = (check_digit_basis % 10);
if(even_number >= 5)
{
total_even_numbers = total_even_numbers + ((( 2 * even_number) % 10) + 1 );
}
else
{
total_even_numbers = total_even_numbers + (2 * even_number);
}
}
check_digit_basis = (check_digit_basis / 10);
}
Luhn_sum = total_even_numbers + total_odd_numbers;
if ((Luhn_sum % 10 ) == 0 )
{
Luhn_validity = 1;
}
else
{
Luhn_validity = 0;
printf("%c for Luhn_validity\n", Luhn_validity);
}
printf("%d for Luhn_validity\n", Luhn_validity);
return Luhn_validity;
}
int main(void)
{
printf("Provide your credit card number:\n");
long long credit_card_number = get_long_long();
int length = length_ccn(credit_card_number);
printf("%i for length\n", length);
char Luhn_validity = Luhn_check(credit_card_number);
printf("%c returned from line 119\n", Luhn_validity);
char credit_card_status;
credit_card_status = get_credit_card_status(credit_card_number, Luhn_validity);
switch (credit_card_status)
{
case 1:
printf("American Express\n");
break;
case 2:
printf("MasterCard\n");
break;
case 3:
printf("Visa\n");
break;
default:
printf("INVALID\n");
}
}
I got:
15 for length
1 for Luhn_validity
returned from line 119
The value of Length is returned to the main function while Luhn_validity isn't. Why?
I cannot make another post because someone posted an incomplete answer only answering to what I already began to implement (see the post before its edits and you'll see that the boolean problem was being corrected and wasn't in the post's title).
credit_card_status = credit_card_status(credit_card_number)
You try to use the same name, credit_card_status, for two different things. If the function is called credit_card_status don't store it's return value in credit_card_status, because that's the function and not a variable. This leads to the error that credit_card_status is not assignable.
error: comparison of constant 350000000000000 with boolean expression is always true
There is no "twoway" comparison a <= x < b in C, you have to use two separate comparisons: a <= x && x < b.
Related
Here is the code:
#include <stdio.h> // printf
#include <cs50.h> // get_long
#include <string.h> // strlen
#include <stdlib.h> // stdlib
int credit_test(string input);
int main(void)
{
string userInput;
// Gets user input, and tests if input is valid
bool isInvalid = false;
do
{
userInput = get_string("Number: "); // Prompts user for input
for(int i = 0, evenIndex = strlen(userInput); evenIndex > i; i++)
{
if(userInput[i] - 48 >= 0 && userInput[i] - 48 <= 9 && (strlen(userInput) == 15 || strlen(userInput) == 16)) // Tests if input is valod
{
isInvalid = false;
}
else
{
isInvalid = true;
break;
}
}
}
while(isInvalid);
int keyValidity = credit_test(userInput);
}
int credit_test(string input)
{
int inputLen;
inputLen = strlen(input);
// Even number calculation
int evenArr[16];
int evenSum = 0;
int evenIndex = 0;
printf("Length: %i\n", inputLen);
for(int i = 0; inputLen > i; i++)
{
int n = i * 2;
evenArr[evenIndex] = input[n] * 2;
if(evenArr[evenIndex] > 0)
{
evenArr[evenIndex] -= 96;
}
if(evenArr[evenIndex] > 9) // Code to split doubles
{
int doubleNum = evenArr[evenIndex];
evenArr[evenIndex] = 1;
evenIndex++;
evenArr[evenIndex] = doubleNum % 10;
}
evenIndex++;
evenSum += evenArr[i];
printf("%i\n", evenArr[i]);
printf("Length: %i\n", inputLen);
}
printf("Length: %i\n", inputLen);
printf("Even Sum: %i\n", evenSum);
// Odd number calculation
int oddArr[16];
int oddSum = 0;
int oddIndex = 1;
for(int i = 0; 16 > i; i++)
{
oddArr[i] = input[oddIndex];
if(oddArr[i] > 0)
{
oddArr[i] -= 48;
}
oddSum += oddArr[i];
oddIndex += 2;
printf("%i\n", oddArr[i]);
}
printf("Odd Sum: %i\n", oddSum);
// Validity test
int finalSum = evenSum + oddSum;
int cardType = finalSum % 10;
printf("Final Sum: %i\n", finalSum);
if(cardType == 0 && (input[0] - 48) == 5)
{
printf("MasterCard \n");
}else if (cardType == 0 && (input[0] - 48) == 4)
{
printf("Visa \n");
}else if(cardType == 0 && (input[0] - 48) == 3)
{
printf("Amex \n");
}else
{
printf("Invalid \n");
}
return 0;
}
I just cannot wrap my head around why, but if you run the code, and keep an eye on the "inputLen" variable it stays what it should be, but in the first for loop which gets the even number in the input, the inputLen stays the same, which is correct, but when the loop finishes, for some reason, the variable changes to 0? So would anyone mind to explain as to why its happening? And sorry if the code is all wonky and bad :)
Thanks so much.
This part of the loop
for(int i = 0; inputLen > i; i++)
{
int n = i * 2;
evenArr[evenIndex] = input[n] * 2;
//...
invokes undefined behavior because the expression input[n] can access memory beyond the used array due to using the expression i * 2 as an index. For example then i is equal to inputLen - 1 then n will bi initialized by the expression 2 * ( inputLen - 1 ) and the value of the expression you are using as an index to access elements of the array input but the array does not have so many elements.
Also in this code snippet
if(evenArr[evenIndex] > 9) // Code to split doubles
{
int doubleNum = evenArr[evenIndex];
evenArr[evenIndex] = 1;
evenIndex++;
evenArr[evenIndex] = doubleNum % 10;
}
evenIndex++;
the variable evenIndex can be incremented twice that again can be a reason of undefined behavior when this variable is used as an index to access elements of the array evenArr.
I have this code below (whole code after this section). I am wanting to include more than one casse for this section of the code:
for(i = 0; i < length; i++)
{
if(numberArray[i] == 1)
{
casse = 2;
}
if(numberArray[i] == 2)
{
casse = 3;
}
if(numberArray[i] == 1 || numberArray[i] == 2)
{
casse = 4;
}
}
So far, the above prints '4' when the value '8213' is entered. This is expected since for each round of for loop the 'casse' variable gets updated, by the time it runs the last integer in the array, the value for 'casse' has undergone many replacements and the end result is the last replacement of '4'.
The objective of the code is to determine which cases (casse) have
been met. There can be more than one case (casse) being met, but as it
stands now, it only has room for one case.
#include <stdio.h>
#include <math.h>
int main(void) {
int odo, value, casse;
int i;
printf("please enter a value for the odometer:\n");
scanf("%d", &odo);
value = odo;
casse = 0;
int length = floor(log10(abs(odo))) + 1;
/* count number of digits */
int c = 0; /* digit position */
int n = value;
while (n != 0)
{
n /= 10;
c++;
}
int numberArray[c];
c = 0;
n = value;
/* extract each digit */
while (n != 0)
{
numberArray[c] = n % 10;
n /= 10;
c++;
}
for(i = 0; i < length; i++)
{
printf("%d, ", numberArray[i]);
}
for(i = 0; i < length; i++)
{
if(numberArray[i] == 1)
{
casse = 2;
}
if(numberArray[i] == 2)
{
casse = 3;
}
if(numberArray[i] == 1 || numberArray[i] == 2)
{
casse = 4;
}
}
printf("\n%d\n", casse);
return 0;
}
Output:
please enter a value for the odometer:
8213
3, 1, 2, 8,
4
Expected output:
please enter a value for the odometer:
8213
3, 1, 2, 8,
Not only '4', but also '3', '2'.
Rather than a single variable that keeps track of the last case, you want an array which keeps track of all cases. For a small number of cases, the array can be a fixed size, with the index as case number and the value in the array as the number of times that case was triggered:
int cases[5] = {0};
for(i = 0; i < length; i++)
{
if(numberArray[i] == 1)
{
cases[2]++;
}
if(numberArray[i] == 2)
{
cases[3]++;
}
if(numberArray[i] == 1 || numberArray[i] == 2)
{
cases[4]++;
}
}
I am in the process of creating hangman in C language, but there is one problem that I cannot quite grasp. When a user correctly guesses one of the letters that the word that is being guessed has, the program replaces all of previously guessed letters to the one user just put. What is the source of this problem?
#include<stdio.h>
#include <stdlib.h>
int main()
{
srand(time(NULL));
int x = 0, isCompleted, matchFound, numberOfTries = 7;
char letterGuess[1];
int randomIndex = rand()%14;
const char *wordArray[14];
const char *guessedWord[10];
const char *usedLetters[17];
for (int k = 0; k < 10; k++) {
guessedWord[k] = "_";
}
wordArray[0] = "butonierka";
wordArray[1] = "centyfolia";
wordArray[2] = "chiroplast";
wordArray[3] = "cmentarzyk";
wordArray[4] = "chrustniak";
wordArray[5] = "budowniczy";
wordArray[6] = "cholewkarz";
wordArray[7] = "cornflakes";
wordArray[8] = "brzydactwo";
wordArray[9] = "germanofil";
wordArray[10] = "lichtarzyk";
wordArray[11] = "lutowniczy";
wordArray[12] = "mikrocysta";
wordArray[13] = "tryskawiec";
const char *wordToGuess = wordArray[randomIndex];
for(int i = 0; i < 10; i++) {
printf(" %s ", guessedWord[i]);
}
printf("\n");
while(numberOfTries != 0 && isCompleted != 10) {
matchFound = 0;
isCompleted = 0;
printf("Please give a lowercase letter\n");
printf("Left tries: %d\n", numberOfTries);
scanf("%s", &letterGuess);
for (int z = 0; z < 17; z++) {
if (usedLetters[z] == letterGuess[0]) {
matchFound = 1;
}
}
if (letterGuess[0] >= 'a' && letterGuess[0] <= 'z' && matchFound == 0) {
usedLetters[x] = letterGuess[0];
x++;
for (int j = 0; j < 10; j++) {
if (letterGuess[0] == wordArray[randomIndex][j])
guessedWord[j] = letterGuess;
matchFound = 1;
}
}
if (matchFound == 0) {
numberOfTries--;
}
for(int z = 0; z < 10; z++) {
printf(" %s ", guessedWord[z]);
}
printf("\n");
} else {
if (matchFound == 1) {
printf("You've already given such letter!!\n");
} else {
printf("Wrong input, please try again!\n");
}
}
for (int k = 0; k < 10; k++) {
if (guessedWord[k] != "_") {
isCompleted++;
}
}
if (isCompleted == 10) {
printf("You have correctly guessed a word! Congrats!!\n");
}
printf("\n\n");
}
printf("The word was: %s\n", wordArray[randomIndex]);
printf("Game over!!\n");
}
The problem is that you're storing letterGuess, rather than individual characters. So each time letterGuess is updated with a new guess, all references to it change. Also, letterGuess is too short, leaving no room for the terminating null character.
The best solution is to make letterGuess a char (or an int), not an array, and to make guessedWord a char [] rather than a char *[]. There is no reason to use strings for single characters. That will solve the string-sharing problem.
So I understand how to perform calculations on integers represented in strings and then printing the result in a string. But I'm lost on how to do the same thing with a decimal in the number represented in a string.
Here's how I did it with integers. This part of the code is adding together two integers:
int answer = 0;
char str1[100];
int count = 0;
int total = 0;
int k = 0;
int diff = 0;
if (ele == ele2) {
for (k = strlen(op1) - 1; k > -1; k--) {
if ((strspn(operand, "+") == strlen(operand))) {
answer = (op1[k] - '0') + (op2[k] - '0');
} else if ((strspn(operand, "-") == strlen(operand))) {
answer = (op1[k] - '0') - (op2[k] - '0');
}
total += (pow(10, count) * answer);
count++;
}
sprintf(str1, "%d", total);
printf("Answer: %s ", str1);
}
Output
// 12 + 14
Answer: 26 // Answer given as a string
Example
12.2 + 14.5 // Three strings
Answer: 16.7 // Answer as string
Current Attempt:
for (k = strlen(argv[1]) - 1; k > -1; k--) {
if (argv[1][k] == '.') {
dec = k;
} else {
answer = (argv[1][k] - '0') + (argv[3][k] - '0');
total += (pow(10, count) * answer);
count++;
}
}
// needs to be converted to a long?
// ele is the length of the operand
total = total / pow(10, ele - dec);
sprintf(str1, "%d", total);
printf("Answer: %s ", str1);
Sharing a simple algo to begin with (and assuming your adding integer funciton works fine).
A decimal number is basically two integers separated by ".".
Identify the position of "." and grab the two sides of the integer as integerPart, decimalPart
One caveat on getting the decimalPart is that the length of all the decimalParts should be same, if not, add "0"s in the suffix.
Add the integerPart, add the decimalPart and handle the carryForwards in the decimalPart.
So,
12.2 + 14.95
= (12 + 14) (20 + 95)
= 26 115
= 26+1 15
= 27.15
This is a quick and dirty implementation: no parameter check, no deep test only an idea of how you should process.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int total_digits;;
int decimal_points;
int *number;
} NUMBER, *DECIMALNUMBER;
DECIMALNUMBER initilize(char *str)
{
DECIMALNUMBER result = calloc(1, sizeof(NUMBER));
int in_decimal = 0;
char *s;
int i;
for (s = str; *s; s++)
{
if (isdigit(*s))
{
result->total_digits++;
if (in_decimal)
{
result -> decimal_points++;
}
}
else if (*s == '.')
{
in_decimal = 1;
}
else
{
return NULL;
}
}
result->number = calloc(result->decimal_points, sizeof(int));
i=0;
for (s = str; *s; s++)
{
if (isdigit(*s))
{
result->number[i++] = (int)(*s - '0');
}
}
// printf("result->total_digits is %d\n",result->total_digits);
// printf("result->decimal_points is %d\n",result->decimal_points);
// printf("result is %d\n",result->number[--i]);
// printf("result is %d\n",result->number[--i]);
// printf("result is %d\n",result->number[--i]);
return result;
}
void print_number(DECIMALNUMBER p)
{
int i;
for (i=0; i<p->total_digits; i++)
{
if (i==p->total_digits - p->decimal_points) {
printf(".");
}
printf("%d", p->number[i]);
}
printf("\n");
}
DECIMALNUMBER sum(DECIMALNUMBER a, DECIMALNUMBER b)
{
int max_decimals = a->decimal_points>b->decimal_points ? a->decimal_points : b->decimal_points;
int max_digits_count = a->total_digits>b->total_digits ? a->total_digits : b->total_digits;
DECIMALNUMBER result = calloc(1, sizeof(NUMBER));
result->total_digits = max_digits_count;
result->decimal_points = max_decimals;
result->number = calloc(max_digits_count, sizeof(int));
int i1 = a->total_digits-1;
int i2 = b->total_digits-1;
int i3 = result->total_digits-1;
int remainder = 0;
int summed;
while (i1 >= 0 || i2 >=0)
{
int aa = i1 < 0 ? 0 : a->number[i1];
int bb = i2 < 0 ? 0 : b->number[i2];
summed = aa + bb + remainder;
result->number[i3] = summed % 10;
remainder = summed / 10;
i1--;
i2--;
i3--;
}
return result;
}
int main()
{
DECIMALNUMBER a = initilize("12.2");
DECIMALNUMBER b = initilize("16.7");
print_number(a);
print_number(b);
DECIMALNUMBER c = sum (a,b);
print_number(c);
return 0;
}
I got an excersice to make a string calculator which only has an add function. When digits are not seperated, the digits have te make one whole number. When the input is 11 the program may not do 1 + 1 but has to make it eleven.
When I execute the following program it is printing "Sum = 111" on my screen, does anyone know why it is not printing 11 and maybe has a solution?
int main(void)
{
int sum = Add("11");
if(sum == -1)
{
printf("Can not return a sum");
}
else
{
printf("Sum = %d\n", sum);
}
}
extern int Add(char* numbers)
{
size_t string_length = strlen(numbers);
int Sum = 0;
int index = 0;
char number_string[255];
int number = 0;
if(string_length == 0)
{
Sum = 0;
return Sum;
}
else if(string_length == 1)
{
if(isdigit(numbers[0]))
{
Sum = numbers[0] - '0';
}
else
{
return -1;
}
return Sum;
}
else if(string_length >= 2)
{
for(index; index <= string_length; index++)
{
if(isdigit(numbers[index]))
{
strcat(number_string, &numbers[index]);
}
else if(!isdigit(numbers[index]))
{
Sum += atoi(number_string);
memset(number_string, 0, 255);
}
else
{
return -1;
}
}
return Sum;
}
else
{
return -1;
}
}
you function uses strcat, you can debug and see how it works:
1st iteration - append string "11" (&numbers[0] points to begin of the string) to number_string
2nd iteration - append string "1" (&numbers[1] points to 2nd symbol) to number_string
this is how you get "111"
what you need to do is to convert your string to number without concatenation, like this:
int Add(char* numbers) {
int n = 0;
for (; *numbers; numbers++)
if (isdigit(*numbers))
n = n*10 + (*numbers - '0');
return n;
}
Your strcat cats 11 and then cats 1 to number string, so you the 111. Here is a simple way to do this without any built in functions other than printf.
#include <stdio.h>
int main(int argc, char *argv[])
{
int sum = -1;
printf("%d\n", argc);
if (argc == 2) {
sum = Add(argv[1]);
}
if(sum == -1)
{
printf("Can not return a sum\n");
}
else
{
printf("Sum = %d\n", sum);
}
}
int Add(char* numbers)
{
char *ptr = numbers;
char *end = numbers;
int sum = 0;
while (*end >= '0' && *end <= '9') {
end++;
}
for( ; ptr < end; ptr++) {
sum *= 10;
/* *ptr is always positive */
sum += *ptr - '0';
}
return sum;
}