C语言 想查一下信用卡号码是否有效

yh2wf1be  于 9个月前  发布在  其他
关注(0)|答案(3)|浏览(63)

我想检查信用卡号码是否有效,但当我运行代码时,我给予的每个数字作为输入,输出都是无效的。
下面的例子是我应该做的。
以大卫的签证为例:4003600000000014.
为了便于讨论,让我们首先每隔一个数字加下划线,从数字倒数第二个数字开始:
4003600000000014
1.好的,让我们把每个带下划线的数字乘以2:
1·2 + 0·2 + 0·2 + 0·2 + 0·2 + 6·2 + 0·2 + 4·2
这给了我们:
2 + 0 + 0 + 0 + 0 + 12 + 0 + 8
1.现在,让我们将这些产品的数字(即,不是产品本身)加在一起:
2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13
1.现在让我们把这个和(13)加到没有乘以2的数字的和上(从最后开始):
13 + 4 + 0 + 0 + 0 + 0 + 0 + 3 + 0 = 20
1.,和(20)的最后一位是0,所以大卫的卡是合法的!

#include <stdio.h>

int main()
{

    int no;
    printf("Visa number: ");`
    scanf("%d", &no);

    int d_1, d_2, d_3, d_4, d_5, d_6, d_7, d_8, d_9, d_10, d_11, d_12, d_13, d_14, d_15;

    d_15 = no%10;
    d_14 = ((no%100)/10)*2;
    d_13 = (no%1000)/100;
    d_12 = ((no%10000)/1000)*2;
    d_11 = (no%100000)/10000;
    d_10 = ((no%1000000)/100000)*2;
    d_9 = (no%10000000)/1000000;
    d_8 = ((no%100000000)/10000000)*2;
    d_7 = (no%1000000000)/100000000;
    d_6 = ((no%10000000000)/1000000000)*2;
    d_5 = (no%100000000000)/10000000000;
    d_4 = ((no%1000000000000)/100000000000)*2;
    d_3 = (no%10000000000000)/1000000000000;
    d_2 = ((no%100000000000000)/10000000000000)*2;
    d_1 = (no%1000000000000000)/100000000000000;

    int d[7] = {d_2, d_4, d_6, d_8, d_10, d_12, d_14};

    int n,add;

    for (n=1; n<=7; n++)
        if(d[n]>10)
        {
            d[n] = (d[n]%10);
            d[(15-n)+1] = ((d[n]%100)/10);
            int sum=0;
            for (int i=0; i<7; i++)
                sum += d[i];
        }
        else
        {
            add = d_14 + d_12 + d_10 + d_8 + d_6 + d_4 + d_2;
        }

    int sum = add + d_15 + d_13 + d_11 + d_9 + d_7 + d_5 + d_3 + d_1;

    if ((sum % 10) == 0)
    {
        printf("%s\n", "The card is valid");
    }
    else
    {
        printf("%s\n", "The card is invalid");
    }
}
mpbci0fu

mpbci0fu1#

我给予的每一个数字作为输入,输出都是无效的。

太大

OP的int可能是32位的。
阅读文本输入,试图形成int范围外的int是 * 未定义行为 *。其余代码无关紧要。

int no;
scanf("%d", &no);  // attempt to read "4003600000000014" leads to UB.

考虑先将用户输入阅读到 string 中,然后再处理字符。@风向标

char buf[100];

if (fgets(buf, sizeof buf, stdin)) {
  int i;
  sum[2] = { 0, 0 };  // sums of even indexed digits and odd indexed digits.
  // Note: only 1 sum really needed, but using 2 sums to mimic OP's approach

  for (i = 0; isdigit((unsigned char) buf[i]); i++) {
    digit = buf[i] - '0';
    if (i%2 == 0) {
      digit *= 2;
      if (digit >= 10) {
        digit = (digit/10 + digit%10);  
      }
    } 
    sum[i%2] += digit;
  }

  // reject bad input: too long or missing expected end
  if (i > 16 || (buf[i] != '\n' && buf[i] != '\0')) {
    puts("Bad input");
  } else {
    // pseudo code to not give everything away.
    // do math on sum[0], sum[1]
    // if as expected --> success 
  }
}
rm5edbpk

rm5edbpk2#

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

long credit;

int getting_the_final_total_number (void);
void checking_which_kind (void);

int main(void)
{
   credit = get_long("Number: ");

   int i = 0;
   long number_count = credit;

   //finding how many numbers are there.
   while(number_count > 0)
   {
      number_count /= 10;
      i++;
   }

   //we use and because (using or make once true, the code block will work and always telling INVALID)

   if(i != 13 && i != 15 && i != 16)
   {
      printf("INVALID\n");
      return 0;
   }

   
   int total = getting_the_final_total_number(); //adding sum_1 and sum_2

   if(total % 10 != 0)
   {
      printf("INVALID\n");
      return 0;
   }

   checking_which_kind();

}

//assigning the credit to another variable for the loop
int getting_the_final_total_number (void)
{
   long credit_one = credit;

   int mod_1;
   int mod_2;

   int sum_1 = 0;

   int m;
   int d;
   int sum_2 = 0;

   do
   {
      //cutting the number into two pieces with all the last numbers and all the second-last-numbers

      //cutting the last numbers.
      mod_1 = credit_one % 10;
      credit_one = credit_one / 10;

      sum_1 += mod_1;

      //cutting the second-last-numbers.
      mod_2 = credit_one % 10;
      credit_one = credit_one / 10;

      //doubling the mod_2 (the second-last-numbers)
      mod_2 = mod_2 * 2;

      //making them into one number (if there is 16 or 18 in the product then make them 1 and 6 or 1 and 8. After that add them all together ).

      m = mod_2 % 10;  //This is for only one standing numer like 1 or 2 or 9 etc (but no 12 or 14 or 16)
      d = mod_2 / 10;    //This is for ten's digit to make sure to become ONE standing digit

      sum_2 = sum_2 + m + d;
   }
   while(credit_one > 0);

   return sum_1 + sum_2;
}

 //checking the first two number of credit
void checking_which_kind (void)
{
   long cc = credit;

   do
   {
    cc = cc / 10;
   }
   while(cc > 100);

   if(cc / 10 == 5 && (cc % 10 > 0 || cc % 10 < 6))
   {
      printf("MASTERCARD\n");
   }
   else if(cc / 10 == 3 && (cc % 10 == 4 || cc % 10 == 7))
   {
      printf("AMERICAN EXPRESS\n");
   }
   else if(cc / 10 == 4 && cc % 10 >= 0)
   {
      printf("VISA\n");
   }
   else
   {
      printf("ERROR");
   }
}
noj0wjuj

noj0wjuj3#

考虑将用户输入声明为long long数据类型,以便最多存储16位数字。

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

int main(void) 
    {
    // Prompt for Input
    long long n;
    do
    {
        n = get_long_long("Number: ");
    }
    while (n < 0);

    // Calculate Checksum
    int l;
    int m;
    int sum;
    long long first = n;
    long long first_two = n;
    int f = 0;
    int p = 0;
    int a = 0;
    int z = 0;
    int y = 0;
    int x = 0;
    do
    {
        l = n % 10;
        a++;

        n = n / 10;

        if (a % 2 == 1)
        {
            z = z + l;
        }

        if (a % 2 == 0)
        {
            if ((2 * l) > 9)
            {
                m = (2 * l) % 10;
                f = (2 * l) / 10;
                p = p + f + m;
            }
            else
            {
                x = x + (2 * l);
            }

            y = p + x;
        }
    }
    while (n > 0);

    sum = z + y; // checksum value

    // Check for card length and starting digits

    while (first_two > 99)
    {
        first_two = first_two / 10;
    }

    while (first > 9)
    {
        first = first / 10;
    }

    // Print Card name or Invalid

    if ((sum % 10 == 0) && (a == 15) && ((first_two == 34) || (first_two == 37)))
    {
        printf("AMEX\n");
    }

    else if ((sum % 10 == 0) && (a == 16) && ((first_two > 50) && (first_two < 56)))
    {
        printf("MASTERCARD\n");
    }

    else if ((sum % 10 == 0) && (a == 13 || a == 16) && (first == 4))
    {
        printf("VISA\n");
    }

    else
    {
        printf("INVALID\n");
    }
}

相关问题