Okay, I admit I have no business doing the "hacker edition" problems, but I am having so much fun with this that I want to do ALL THE PROBLEMS!
Anyway. I'm working on pset1 hacker edition "credit."
In my "main" function, I start by calling "getLikeCC" to grab a long long unsigned variable that has 16 digits (excluding a number consisting of all 0s).
...I just realized that not all CC numbers have 16 digits. I didn't read that part carefully enough. That's okay! I'll rework that. It doesn't affect my question.
long long unsigned getLikeCC();
int checkCC();
int main(){
unsigned long long ccInput = getLikeCC();
This works, and I double-checked the variable type with a printf statement:
printf("When the main function got ahold of ccInput, it now looked like this: %llu\n",ccInput);
And got
After running 'getLikeCC', the value of ccInput was 1234123412341234
(which is what I typed in).
So I now have a 16-digit number in a variable of type "long long unsigned".
Next, I pass ccInput to a second function, called checkCC:
int result = checkCC(ccInput);
The goal of checkCC is to evaluate whether the number is invalid, Amex, Visa, or Mastercard. It returns either 0, 1, 2, or 3, and these results will be used by the main function to spit out the result.
CheckCC takes successively higher (by 10-fold) modulus of CC along with some subtraction to zero out the end values, and division to get the result to single digits, and stores each number of checkCC into an array of integers. This works just fine, as I have found by using test numbers and printing the results from within the sub-function.
However, when I pass ccInput to checkCC, the complier suddenly thinks that ccInput is an integer. Thus it evaluates it as some long crazy occasionally negative number, and when I used printf to debug, the compiler tells me it's an int, not an llu.
int checkCC(ccInput){
printf("When we started running the checkCC program, ccInput looked more like this: %llu",ccInput);
Here's what the compiler thinks about that!:
credit.c:61:95: error: format specifies type 'unsigned long long' but the argument has type 'int' [-Werror,-Wformat]
My only kind of guess is that "getLongLong()" gets a signed rather than unsigned integer, and somehow that is throwing things off... I don't know the real relevance of signed vs unsigned, but I figured I'll never need a negative number and that making it signed would just introduce the potential for error, so I typed the variable as unsigned.
Thanks for any help you can offer!
UPDATE:
I decided to un-abstract that step, and move on with life for now.
In my very next step, though, I abstracted away the function that doubles alternating numbers and sums their digits...
And I'm having a similar problem; an undeclared argument type is treated as an integer (instead of taking the array I wanted it to take.)
So an update on my problem would be: how can I force an argument to take a variable as a desired type?
ADDENDUM: #########################################################
This is the version of the code that I was using when I submitted this question. Since then, I have removed all abstraction and made some modifications, and my final code passes all the "check" tests. However, my question remains: what would it take to properly pass a long long as an argument to a function?
#include <stdio.h>
#include <cs50.h>
#include <math.h>
#include <string.h>
long long unsigned getLikeCC();
int checkCC();
int main(){
unsigned long long ccInput = getLikeCC();
//continues prompting for CC number until user inputs 16-digit number with no dashes that isn't all zeroes.
//if the user won't cooperate, returns 100000000000 instead.
printf("When the main function got ahold of ccInput, it now looked like this: %llu\n",ccInput); //throws error: format specifies type "unsigned long long" but the argument has type "int"
if (ccInput > 100000000000){
printf("Just to be thorough, in the main function within the \'if\' condition, ccInput looked like this: %llu\n",ccInput);
int result = checkCC(ccInput);
//the spec says to put only AMEX, INVALID, etc on the last line of output, which made me think if I started a new line, it would satisfy the spec. Obviously when I ran the check I found out I was wrong, and modified these.
if(result == 0){printf("It looks like you made a mistake, or else you are trying to enter a fake number.\nINVALID\n");}
if(result == 1){printf("Purchasing various products on Amazon.com using your American Express number %llu.\nAMEX\n",ccInput);}
if(result == 2){printf("Purchasing various products on Amazon.com using your Mastercard number %llu.\nMASTERCARD\n",ccInput);}
if(result == 3){printf("Purchasing various products on Amazon.com using your Visa number %llu.\nVISA\n",ccInput);}
// printf("%llu\n",ccInput);
}
else {printf("That's not even the right number of digits. Either you don't have a credit card, or you shouldn't be trusted with one.\nINVALID\n");}
return 0;
}
long long unsigned getLikeCC(){
int i = 0;
printf("Enter your credit card number.\n...I prooooomise nothing bad will happen.\n\n\n...no, really!\nTrust us! Type it in riiiight here-->");
long long unsigned ccInput = GetLongLong();
while (ccInput < 1000000000000000 || ccInput > 9999999999999999){
if(i < 10){
if (i>4 && i<7){printf("\nAre you sure you're looking at the rectangle plastic thing? Perhaps you should ask someone to help you.\n");}
if (i > 6){printf("\nMaybe this will help... try copying this URL into your browser. It's totally not a virus.\nhttp://us.123rf.com/450wm/tombaky/tombaky0903/tombaky090300287/4577555-credit-card-with-black-arrow-computer-cursor.jpg\n");}
printf("Not to be rude... but that's actually not a credit card number. Would you mind trying again, please: ");
ccInput = GetLongLong();
i++;
}
else {return 100000000000;}
}
printf("After running \'getLikeCC\', the value of ccInput was %llu.\n",ccInput);
return ccInput;
}
int checkCC(ccInput){
//if I enter a test cc into this sub-function, the output returns to the main function and everything works. But when I pass in ccInput, it fails.
//after some bug-checking using printf, I realized that ccInput is converted
//to an integer when being passed to this function.
//by taking successivly larger (by 10x) modulus of the credit card number and dividing,
//we get digits of credit card number one at a time and store them in a new array of integers.
printf("When we started running the checkCC program, ccInput looked more like this: %llu",ccInput);
//long long unsigned testNumber = 4444555533332222;
long long unsigned subtractThis = 0;
long long unsigned bigNumber = ccInput;
// printf("But SOMEHOW, after taking bigNumber = ccInput, even though ccInput is %llu, BigNumber is %llu!\n",ccInput, bigNumber);
int arrayCC[16];
printf("\n");
long long unsigned j = 1;
for(int i=0; i<16; i++){
long long unsigned k = j * 10;
int arraySpot = 15 - i;
printf("j = %llu. Big Number: %llu; subtractThis: %llu.",j, bigNumber, subtractThis);
bigNumber = bigNumber - subtractThis;
printf(" Big Number minus SubtractThis: %llu.,", bigNumber);
subtractThis = bigNumber % k;
printf(" Result modulo %llu: %llu.",k, subtractThis);
arrayCC[arraySpot] = subtractThis / j;
printf(" So we take subtractThis divided by %llu to get the value we store in the array, %i.\n", j, arrayCC[arraySpot]);
j *= 10;
//printf("%llu, %llu, %i\n",bigNumber, subtractThis,arrayCC[arraySpot]);
}
printf("\n");
return 0;
}