Я программист в первый раз, попробовав заполнить простую программу командной строки как часть first assignment для онлайн-курса, который я принимаю, но, похоже, я попал контрольный блок, который я не могу понять с помощью GDB или моих собственных исследований.Оператор 'if' в C не выполняется, хотя условия выполнены
После нескольких часов перезаписывания и часов отладки я, наконец, получил код для компиляции. Предполагается, что в качестве входа предполагается ввести номер кредитной карты, а затем проверить, действительно ли она соответствует спецификациям задания. Я использовал тестовый номер отсюда: PayPal Test Credit Cards
Странно, когда я ввожу номер карты AMEX, он правильно выдает текст «AMEX», но когда я пытаюсь выполнить визу или основную карту, он печатает «INVALID ».
В GDB я нарушил функцию Verify и, похоже, неправильно пропустил эти два оператора 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. Я бы напечатал totalDigits, firstDigit и secondDigit в GDB прямо перед тем, как пройти через две неработающие строки, и все выглядело правильно. Итак, я в тупике, почему работает линия 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;
}
}
'secondDigit == (4 | 7)' [не делает то, что вы думаете, что он делает] (https://en.wikipedia.org/wiki/Bitwise_operations_in_C#Bitwise_OR_.22.7C.22) ... – scohe001
Изменить 'secondDigit == (4 | 7)' to '((secondDigit == 4) || (secondDigit == 7))'. – haccks