0

I'm working on a program that checks the validity of credit card numbers for the CS50 class I'm taking (it's legal I swear haha) and I'm currently working on correctly getting the first two numbers of each CC# to check what company it is from. I've commented what each part does for clarity and also commented where my problem arises.

#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#include <math.h>
#include <string.h>
int main(void)
{
  long long ccn = get_long_long("Enter CCN: \n");
  int count = 0;
  long long ccn1 = ccn;
  // finds the amount of digits entered and stores that in int count.
  while (ccn1 != 0)
  {
     ccn1 /= 10;
     +count;
  }
  printf("%i \n", count);
  // ln 17- 19 should take int count, subtract two, put that # as the power of 10, 
  // then divide the CC# by that number to get the first two numbers of the CC#.
  long long power = count - 2;
  // here is where i get the error. its a long long so it 
  // should hold up to 19 digits and im only storing 14 max 
  // but it says that 10^14th is too large for type 'int'
  long long divide = pow(10,power);
  long long ft = ccn / divide;
  printf("power: %i \n", power); //ln 20-22 prints the above ints for debug
  printf("Divide: %lli \n", divide);
  printf("First two: %lli \n", ft);
  string CCC;
  // ln 24-35 cross references the amount of digits in the CC#
  // and the first two digits to find the comapany of the credit card
  if ((count == 15) && (ft =  34|37))
  {
    CCC = "American Express";
  }
  else if ((count == 16) && (ft = 51|52|53|54|55))
  {
    CCC = "MasterCard";
  }
  else if ((count = 13|16) && (ft <=49 && ft >= 40))
  {
      CCC = "Visa";
  }
  printf("Company: %s\n", CCC);
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    Using `pow` for integer calculations is a bad idea. – Eugene Sh. Oct 20 '17 at 18:34
  • Not your problem, but you probably did not want to use this: `else if ((count == 16) && (ft = 51|52|53|54|55))`. First of all, `|` is bitwise or, not logical, you should use `||` and you cannot chain it in a way you did. And `=` is assignment operator, not equality. – Honza Dejdar Oct 20 '17 at 18:36
  • From one *beginner* to another, *your guess is as good as mine* in C, meaning both of our guesses are likely wrong even if we observe them "working" because even a subtle error earlier on will mean the entire foundations of our studies are founded on bad assumptions. Thus, as beginners we need a different approach to ensure the validity of our textbooks. – autistic Nov 06 '17 at 07:02

1 Answers1

0

The first issue is the +count in the loop. This should be ++count. Because of this, count stays at 0 and power = -2. You can avoid all that power stuff. You already have the loop, you can use it to get the first two digits:

int ft = 0;
while (ccn1 != 0)
{
    // When you are down to 10 <= ccn1 < 100, store it
    if (ccn1 < 100 && ccn1 > 9) ft = ccn1;
    ccn1 /= 10;
    ++count;
}

Your second issue is how you do your comparisons.

if ((count == 15) && (ft =  34|37))

First, = is assignment, and == tests equality. Second, | is bitwise OR, || is logical OR. Third, you can't test multiple values like that. Correct way:

if ((count == 15) && (ft == 34 || ft == 37))
001
  • 13,291
  • 5
  • 35
  • 66
  • ive done all this and im still having the same error: credit.c:18:18: runtime error: value 1e+14 is outside the range of representable values of type 'int' – Noah Sparks Oct 20 '17 at 19:25
  • @NoahSparks `long long` should work (see this test: https://ideone.com/YymSkG). But, if you use the `while` loop I have presented, you can delete all that (from after the loop to `string CCC;`) because all that code is doing is getting `ft` which my loop already provides. – 001 Oct 20 '17 at 19:39
  • @JohnnyMopp Actually, I was thinking of writing an answer discouraging the use of `long long` here. Most significantly, as `get_long_long` first reads input from standard input in the form we need it (a sequence of decimal digits), translation to `long long` and discarding that array is wasteful. The array is what we should validate here. Additionally, in what usecase is it appropriate to have *negative* (using the `-` prefix), *octal* (using the `0` prefix) or *hexadecimal* (using the `0x` prefix) user input translating to a *credit card number*? – autistic Nov 06 '17 at 07:18
  • The book encourages students to use the wrong tool for the job. That is unfortunate, but not unexpected... at least for me, as the entire `` include is used despite the high-level memory leak which *isn't a bug*; it's a feature because the author thinks `scanf`, `fgets` and `fgetc` are too difficult for you to learn, which I consider offensive. Nonetheless, it's certainly not unacceptable due to being expected; we must accept that which we expect, right? A book which subtly treats you like a baby is unlikely to teach you as much as one which is respectful, after all... – autistic Nov 06 '17 at 07:41
  • It turns out I recalled incorrectly. The reason Malan doesn't want you using `scanf`, `fgets` and `fgetc` is because he thinks `malloc` and `free` is too difficult to learn. That's even worse, on account of the fact that none of those functions require `malloc` and `free`. I suspect he's a bit confused himself, and he meant to write that `scanf`, `fgets` and `fgetc` are too difficult to learn; they are quite difficult and deceptive, but as is the rest of the C language, so I still think Malan is (likely unintentionally though subtly) insulting his students. – autistic Nov 06 '17 at 08:08
  • @Sebivor A `long long` is probably not the best choice but it seems to be a prerequisite. Not sure what your saying about the prefix stuff. – 001 Nov 06 '17 at 18:47
  • @JohnnyMopp In order to understand what I'm saying about the *prefix* stuff, you must first try to think of a circumstance where it's useful (as opposed to confusing) to have negative credit card numbers. Then, you must try to enter a negative credit card number. Repeat the procedure for using `0x` rather than `-` as a prefix for hexadecimal, and `0` for octal. – autistic Nov 07 '17 at 05:50
  • @JohnnyMopp Alternatively, I suppose you could try to point out in the code where negative, hexadecimal and octal input is explicitly forbidden in the code... – autistic Nov 07 '17 at 05:51