#c #if-statement #cs50
#c #if-оператор #cs50
Вопрос:
#include <math.h>
#include <stdio.h>
#include <stdbool.h>
#include <cs50.h>
short unsigned int numlen(unsigned long long n);
bool isValidCC(unsigned long long int n);
unsigned short int first_n_nums(unsigned short int n, unsigned short int x);
int main(void)
{
unsigned long long num = 0;
num = get_long("Enter your card number ");
if(numlen(num) == 15 amp;amp; (first_n_nums(num, 2) == 34 || first_n_nums(num, 2) == 37) amp;amp; isValidCC(num) == true)
{
printf("AMEXn");
}
else if((numlen(num) == 13 || numlen(num) == 16) amp;amp; first_n_nums(num, 1) == 4 amp;amp; isValidCC(num) == true)
{
printf("VISAn");
}
else if(numlen(num) == 16 amp;amp; (first_n_nums(num, 2) == 51 || first_n_nums(num, 2) == 52 || first_n_nums(num, 2) == 53 || first_n_nums(num, 2) == 54 || first_n_nums(num, 2) == 55) amp;amp; isValidCC(num) == true)
{
printf("MASTERCARDn");
}
else
{
printf("INVALIDn");
}
}
unsigned short int first_n_nums(unsigned short int n, unsigned short int x)
{
while(n > pow(10,x))
{
n /= 10;
}
return n;
}
short unsigned int numlen(unsigned long long n)
{
short unsigned int count = 0;
while (n !=0)
{
n /= 10; //removes last digit
count ; //counts the num of digits removed
}
return count;
}
bool isValidCC(unsigned long long int n)
{
// take user input and add elements to array in reverse
int arr1[(numlen(n))]; // declares but can't Initialize an array of n ;
for (int i = 0; i < (int)sizeof(arr1)/sizeof(int) ; i )
{
arr1[i] = 0;
}
for (int i = 0 ; i <(int) (sizeof(arr1)/sizeof(int)) ; i )
{
arr1[i] = n % 10; //Appends last digit to an array
n /= 10; // removes that last digit
}
// since arr1 = x digits long, arr2 is every second digit so its x/2 long
int arr2[((sizeof(arr1)/sizeof(int))*2)];
//initializing garbage data to 0
for (int i = 0; i < sizeof(arr2)/sizeof(int) ; i )
{
arr2[i] = 0;
}
// multiplies, seperates, and sums arr2 elements
int sum_of_arr2 = 0;
for (int i = 1, a = 0, b = 0 ; i < (sizeof(arr1)/sizeof(int)) ; i = 2) // sizeof(array) = n of elements * sizeof(type of n)
{
a = arr1[i] * 2;
if( a > 9)
{
b = a % 10;
a /= 10;
arr2[i] = b;
sum_of_arr2 = b;
}
arr2[i-1] = a; // cz i currenrly is one idex ahead
sum_of_arr2 = a;
}
// adds other elements of arr1 to sum_of_arr2
for (int i = 0 ; i < (sizeof(arr1)/4) ; i = 2) // sizeof(array) = n of elements * sizeof(type of n)
{
sum_of_arr2 = arr1[i];
}
// returns true or false
if (sum_of_arr2 % 10 != 0)
{
return false;
}
else
{
return true;
}
}
Может кто-нибудь, пожалуйста, объяснить, почему это не удается для таких значений, как:
371449635398431 — ожидаемый «AMEX n», а не «НЕДЕЙСТВИТЕЛЬНЫЙ n»
5555555555554444 — ожидаемый «MASTERCARD n», а не «НЕДЕЙСТВИТЕЛЬНЫЙ n»
5105105105105100 — ожидается «MASTERCARD n», а не «VISA n»
4111111111111111 — ожидаемый «VISA n», а не «НЕДЕЙСТВИТЕЛЬНЫЙ n»
4222222222222 — ожидаемый «VISA n», а не «НЕДЕЙСТВИТЕЛЬНЫЙ n»
Комментарии:
1. Нам нужно посмотреть, что
first_n_nums
,isValidCC
, иnumlen
помочь. Этот код как есть не будет компилироваться, поэтому мы не можем даже сделать хорошее предположение. Я бы открыл отладчик и посмотрел, что возвращается для каждой функции, чтобы каждая функция выполняла то, что вы ожидаете…2. Вместо того, чтобы допускать неточности FP, перейдите
while(n > pow(10,x))
к решению на основе целых чисел.3. Вы не должны использовать плавающую точку для всего этого. На самом деле, вам, вероятно, не следует использовать целые числа. Строки будут предоставлять более общее представление, на которое не распространяются ограничения по длине.
4. Вы могли бы
return (sum_of_arr2 % 10 == 0);
точно так же, что ваше обнуление массива бесполезно, потому что вы все равно будете заполнять каждую цифру…5. Сегодня хороший день, чтобы научиться пользоваться отладчиком. Каждый день — хорошее время, чтобы научиться пользоваться отладчиком. Это также хороший день для изучения концепции модульных тестов. Вы
first_n_nums
делаете то, что вы хотите, чтобы он делал?
Ответ №1:
Ваша проблема в вашей функции
unsigned short int first_n_nums(unsigned short int n, unsigned short int x)
Вы передаете unsigned short int
вместо unsigned long long
, так что вы можете просто получить максимальное значение unsigned short int
вместо реального значения.
Вывод:
371449635398431 - "AMEXn"
5555555555554444 - "MASTERCARDn"
5105105105105100- "MASTERCARDn"
4111111111111111 - "INVALIDn" - Note that the output you said you were expecting is incorrect because the input length is 14 instead of 13.
4222222222222 - "VISAn"