CS50 Неделя 1, Кредит - Если проблема сравнения?Инт размерный лимит? - PullRequest
1 голос
/ 07 июля 2019

Я новичок в CS50 и C, и в настоящее время я работаю над назначением недели 1 «Кредит». У меня большая часть работы работает, но я сталкиваюсь с проблемой, когда независимо от того, насколько верным я считаю утверждение, мое сравнение, если оно помечено как ложное. Моя логика выключена, или я что-то упустил? Есть ли ограничение на размер числа, которое я могу использовать в сравнениях If?

Вот мой код:

#include <cs50.h>
#include <stdio.h>

unsigned char cardArray[20];
unsigned long creditCard;
string cardType; //String used for checking what type of credit card     has been submitted.
//int remainder;
int n = 0;//Increment array position
int x = 0;

int main(void)
{

creditCard = get_long("Input: "); //Prompt user for CC
printf("%lu", creditCard);

while(creditCard > 0 && creditCard != 0) //Take CC Int and convert to Char Array for math functions
{
    cardArray[n] = (creditCard % 10); //Modulus creditCard remainder
    //printf("%i\n", n); //Array indices check
    creditCard = (creditCard / 10); //Reduce creditCard by factor of 10
    printf("%d\n", cardArray[n]);
    n += 1; //increment Array indices
}

printf("Pos 15: %d\n", cardArray[15]);

//Use if >= to check size of creditCard
if(creditCard > 1000000000000 && creditCard <= 9999999999999){printf("X3: %s\n", cardType); //Check for creditCard length of 13 
    if(cardArray[12] == 4){
        cardType = "VISA\n";
    }
}else     printf("X: %s\n", cardType); 

if(creditCard >= 100000000000000 && creditCard <= 999999999999999){ printf("X1: %s\n", cardType);//Check for creditCard length of 15
    if(cardArray[14] == 3 && (cardArray[13] == 4 || cardArray[13] == 7)){//If 15 AND starts with 34 OR 37 then set card value to American Express
        cardType = "AMEX\n"; 
    }    
}else     printf("X: %s\n", cardType);

if(creditCard >= 1000000000000000 && creditCard <= 9999999999999999){printf("X2: %s\n", cardType); //Check for creditCard length of 16
    if(cardArray[15] == cardArray[15]){//Does it start with 4? set card value to Visa
        cardType = "VISA\n";
            printf("%s", cardType); 
    }
else     printf("X: %s\n", cardType);
    if(cardArray[15] == 5 && (cardArray[14] == 1 || cardArray[14] == 2 || cardArray[14] == 3 || cardArray[14] == 4 || cardArray[14] == 5)){//Does it begin with 51, 52, 53, 54, or 55? set card value to Master Card     
        cardType = "MASTERCARD\n";
    }    
}    
else cardType = "INVALID\n";

printf("%s", cardType); 

}

Я протестировал несколько строк printf, чтобы увидеть, куда движется мой код. Если я изменю сравнения на что-то вроде 1 == 1, я могу пометить сравнение как истинное, но использование сравнений, таких как creditCard> = 1000000000000, всегда будет неудачным, даже если я передаю 10000000000000.

1 Ответ

1 голос
/ 07 июля 2019

unsigned long на вашей цели, скорее всего, 32-битное значение.2 32 = 4294967296, поэтому, очевидно, сравнение с 10000000000000, например, всегда будет иметь значение false.

Если ваш компилятор не выдавал никаких предупреждений, вам следует посмотреть настройки вашего компилятора.

Измените тип creditCard на unsigned long long или лучше uint64_t (объявлено в <stdint.h>).Затем вы должны также указать литеральное целое число с суффиксом ULL, например:

creditCard >= 100000000000000ULL

Однако реализация имеет серьезные недостатки.Вы получаете номер карты как целое число, а затем конвертируете его в строку.Поскольку ваш тип данных не будет содержать номер кредитной карты, строка и целое число будут неправильными.Номера кредитных карт не являются арифметическими объектами, и хранение в виде целого числа является плохой идеей по ряду причин, по которым просто диапазон - даже uint64_t хорош только для 19 цифр - что может быть достаточно на данный момент, но, возможно, не в будущем.Номер должен быть получен и обработан как строка.Преимущества состоят в том, что вы можете выполнить более сложную проверку, разрешить пробелы в группировке цифр и не потерять первые нулевые цифры.

Сравнение строк на нормализованных строках цифр (т. Е. С удаленными пробелами) будет работать так же, как и арифметическое сравнение,Например:

if( strcmp( cardNumberString, "10000000000" ) >= 0 )

достигает того же результата, что и:

if( cardNumberUnsLongLong >= 10000000000ULL )
...