我是第一次尝试完成一个简单的命令行程序的程序员,作为first assignment的一部分用于我正在进行的在线课程,但我似乎遇到了一个障碍,我可以'找出GDB或我自己的研究。
经过几个小时的重写和几个小时的调试,我终于得到了下面的代码来编译。该程序应该将信用卡号作为输入,然后根据分配的规范检查它是否有效。我在这里使用了一个测试号码:PayPal Test Credit Cards
奇怪的是,当我输入AMEX卡号时,它正确地生成了文本" AMEX",但是当我尝试签证或万事达卡时,它会打印" INVALID&#34 ;。
在GDB中我破坏了验证功能,它似乎错误地跳过了这两个if / else if语句而没有进入Checksum函数,即使条件似乎已经满足。
if (firstDigit == 4 && totalDigits == (13 | 16) && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Visa.
...
else if (firstDigit == 5 && secondDigit == (1 | 2 | 3 | 4 | 5) && totalDigits == 16 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Mastercard.
...
正确执行的AMEX代码行是:
else if (firstDigit == 3 && secondDigit == (4 | 7) && totalDigits == 15 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid American Express.
所有三行的参数似乎格式完全相同。这就像我可以进入GDB那样。我先在GDB中打印totalDigits,firstDigit和secondDigit,然后单步执行上述两条非执行行,一切看起来都正确。所以我很难过,为什么AMEX系列会执行,而不是其他系列?
先谢谢大家。这是我试过写的hello.c之后的第一个程序,所以如果看起来我做了一些奇怪/错误的话,我绝对会接受任何批评或建议。
完整代码:
checker.c
#include <stdio.h>
#include <stdlib.h>
int MAX = 16;
int* DigitSort(unsigned long long x, int* array);
int Verify(int* array);
int main (void)
{
int* output = malloc (sizeof(int) * (MAX + 2)); // creates a blank array for the individual digits of the card number.
unsigned long long userInput = 0;
do
{
printf("Please enter a credit card number:\n");
scanf("%lld", &userInput);
}
while (userInput <= 0); // checks to make sure the user entered a number.
switch(Verify(DigitSort(userInput, output))) // sorts the user's input into individual digits and verifies the card type and validity.
{
case 1 :
printf("VISA\n");
break;
case 2 :
printf("MASTERCARD\n");
break;
case 3 :
printf("AMEX\n");
break;
case 0 :
printf("INVALID\n");
break;
default :
printf("INVALID\n");
}
free(output);
return 0;
}
int Verify(int* array) // verifies whether or not a card number is valid. Must pass the function a sorted array of individual digits.
{
int* cardNumber = array;
int firstDigit = cardNumber[0];
int secondDigit = cardNumber[1];
int totalDigits = 0;
int Checksum(int* cardNumber, int totalDigits);
int i = 0;
while (firstDigit >= 1 && cardNumber[i] >= 0) // this step counts the number of digits in the array.
{
totalDigits = totalDigits + 1;
i++;
}
if (firstDigit == 4 && totalDigits == (13 | 16) && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Visa.
{
return 1;
}
else if (firstDigit == 5 && secondDigit == (1 | 2 | 3 | 4 | 5) && totalDigits == 16 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Mastercard.
{
return 2;
}
else if (firstDigit == 3 && secondDigit == (4 | 7) && totalDigits == 15 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid American Express.
{
return 3;
}
else // if the card number doesn't match any of the above conditions or fails the checksum, an 'I' for Invalid is returned.
{
return 0;
}
}
int* DigitSort(unsigned long long x, int* array) // takes a long long as input and sorts it into individual digits
{
int* arrayReversed = malloc (sizeof(int) * (MAX + 2)); // creates a new array to hold the reversed order of digits.
int i = 0;
arrayReversed[0] = 0;
if (i < (MAX - 1) && x >= 10)
{
do
{
arrayReversed[i] = x % 10;
x = x / 10;
i++;
}
while (i < (MAX -1) && x >= 10);
}
if (i < MAX && x >= 1 && x <= 9)
{
arrayReversed[i] = (int) x;
x = (x - x);
}
if (x == 0)
{
int j = 0;
do
{
array[j] = arrayReversed[i]; // sorts the digits from the reversed array and places them into the sorted array.
j++;
i--;
}
while (j < MAX && i >= 0);
array[j] = -1;
}
free(arrayReversed);
return array;
}
int Checksum(int* cardNumber, int totalDigits)
{
int sum1 = 0;
int sum2 = 0;
int i = (totalDigits - 2);
int j = (totalDigits - 1);
while (i >= 0)
{
sum1 = ((cardNumber[i] * 2)%10) + ((cardNumber[i] * 2)/10) + sum1;
i -= 2;
}
while (j >= 0)
{
sum2 = (cardNumber[j] + sum2);
j -= 2;
}
if (((sum1 + sum2) % 10) == 0)
{
return 0;
}
else
{
return 1;
}
}
答案 0 :(得分:5)
你的第一个问题是:
if (firstDigit == 4 && totalDigits == (13 | 16) && ...
你需要写:
if (firstDigit == 4 && (totalDigits == 13 || totalDigits == 16) && ...
您的第一次检查是寻找0x1D == 29作为位数(因为paisanco指出comment,|
运算符是按位OR运算符) ,并且没有信用卡需要29位数(但不是很长一段时间)。请注意额外的括号,以便清晰和准确。不要乱搞去除它们 - 代码再次无法正常工作。一般情况下,如果您的条件同时包含&&
和||
运算符并使用括号明确地对术语进行分组,请明确说明。
你在其他地方也有类似的问题。碰巧,(4 | 7)
与7
的值相同,因此当第二个数字为7时(但不是4时),条件才有效。但它并不意味着你的意思。
计算机语言与人类语言的工作方式不同。习惯于更冗长地写出条件。其他一些语言为这些条件提供了缩写; C不是这样的语言。