CS50第1周,信用-如果比较问题?整数大小限制?

时间:2019-07-06 23:24:38

标签: c cs50

我是CS50和C的新手,目前正在从事第一周的“信贷”工作。我已经完成了大部分工作,但是我遇到了一个问题:无论我觉得陈述多么真实,如果我的比较将其标记为错误。我的逻辑不对吗,还是我错过了什么?我可以在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,则可以将比较标记为true,但是即使使用10000000000000,也不能使用creditCard> = 1000000000000这样的比较。

1 个答案:

答案 0 :(得分:1)

目标上的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 )