Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a project yet my teacher hasn't taught us about arrays. We need to output =<> signs corresponding to the comparison of one number to another. IE the main number is 1234 and I put in 2315, the output would be <<<> where the signs do not go in the order of the numbers but by this order =, <, >.
I have an idea and that to use an array then to use some code that would read out the whole array and apply rules to it, however I do not know how to implement this. I have been googling for awhile now and nothing I found really helps.
Just to let you know the program has way more steps than just this, all of which I have already completed, I just can't figure out this part. I do not want just the answer, I just want someone to point me in the right direction.
Thanks
EDIT:: The example 1234 and 2315 are bad examples. To give a more definitive idea without giving away too much of the problem so I have work to do is listing num1 and num2 (corresponding to 1234 and 2315) from least to greatest or greatest to least and compare that way. So another example would be 4751 is the main number and I put in 1294. The output would be ==<>. Thanks for the help guys so far. I am learning a lot.
EDIT2:: Thanks guys for the help. I learned a lot. I don't want any more submissions at least until I can upload my code.
Taking you at your word that you've already successfully completed most of your assignment, and by giving you code that you'll have to work through and understand to figure it out and adapt it to your needs, this will do what you want. The fact that you don't have to output the signs in the same order as the numbers themselves is what makes this easier.
#include <stdio.h>
int main(void) {
int num1 = 1234;
int num2 = 2315;
int lt = 0, gt = 0, eq = 0;
while ( num1 > 0 && num2 > 0 ) {
int op1 = num1 % 10;
int op2 = num2 % 10;
if ( op1 < op2 ) {
++lt;
} else if ( op1 > op2 ) {
++gt;
} else {
++eq;
}
num1 /= 10;
num2 /= 10;
}
for ( int i = 0; i < eq; ++i ) {
putchar('=');
}
for ( int i = 0; i < lt; ++i ) {
putchar('<');
}
for ( int i = 0; i < gt; ++i ) {
putchar('>');
}
putchar('\n');
return 0;
}
and outputs:
paul#MacBook:~/Documents/src/scratch$ ./eq
<<<>
paul#MacBook:~/Documents/src/scratch$
This code lets you get the nth digits you can compare and make a count of each symbol you need to return
char nthdigit(int x, int n)
{
while (n--) {
x /= 10;
}
return (x % 10) + '0';
}
And this is how you get the length of a number, check this post
As promised here is the rest of my code. It fixes the issue pointed out in the question but I have another issue. It is probably pretty noticeable but I wanted to post my code so I don't forget again.
#include<stdio.h>//standard inputs and outputs
#include<stdlib.h>//for compare, qsort, srand, and rand function
#include<time.h>//for random numbers at different times
#include<unistd.h>//for fun at the end
int main(void){
int guess, gdig1, gdig2, gdig3, gdig4, random, rdig1, rdig2, rdig3, rdig4;//variables for main
int lt, gt, eq, i, q, temp, holder;//this is for the hints
int g[3],r[3];
printf("Give the computer a few seconds to come up with a super secret passcode.\n");
do{//figuring out a random code
unsigned int iseed = (unsigned int)time(NULL);
srand (iseed);//using an unassigned integer
random = rand()%9000+1000;//generating a random number but limiting it
rdig4 = random%10;
rdig3 = (random/10)%10;
rdig2 = (random/100)%10;
rdig1 = (random/1000)%10;//figuring out the individual digits of the code
} while ((rdig1 == rdig2)||(rdig1 == rdig3)||(rdig1 == rdig4)||(rdig2 == rdig3)||(rdig2 == rdig4)||(rdig3 == rdig4)||(rdig1 == 0)||(rdig2 == 0)||(rdig3 == 0)||(rdig4 == 0));
//^^ some crazy boolean expression making sure the random integer doesnt have any of the same digits.
printf("\nThe actual passcode is:%d.\n",random);//testing in beginning comment out ********
do{
do{
printf("\nEnter in your guess for the passcode: ");
scanf("%d",&guess);//inputting and reading the guessed code
// printf("You entered:%d\n",guess);//just to check comment out at end**
gdig4 = guess%10;
gdig3 = (guess/10)%10;
gdig2 = (guess/100)%10;
gdig1 = (guess/1000)%10;//figuring out the individual digits of the guess code using modulus operator
if (guess > 9999){//the starting loop statement to make sure number is valid. this one is if it is greater than 4 digits
printf("\nPlease use a four digit number for the passcode.\n");
}
else if (guess < 1000){//this one is if it is less than 4 digits
printf("\nPlease use a four digit number for the passcode.\n");
gdig1 = 1;
gdig2 = 1;//used so the computer still loops
gdig3 = 1;
gdig4 = 1;
}
if ((gdig1 == 0) || (gdig2 == 0) || (gdig3 == 0) || (gdig4 == 0)){
break;
}
if ((rdig1 == gdig1) && (rdig2 == gdig2) && (rdig3 == gdig3) && (rdig4 == gdig4)){//to skip this codeblock and move onto next
break;
}
if (guess > 9999){
break;
}
if (guess < 1000){
break;
}
printf("\n%d %d %d %d\n",rdig1,rdig2,rdig3,rdig4); //used to testing comment out at end
printf("\n%d %d %d %d\n",gdig1,gdig2,gdig3,gdig4);
while (guess > 0){
g[i++] = guess % 10;
guess /=10;
}
do{//took a long long LONG time to get
for(i = 0; i<3;i++){
if(g[i] > g[i+1]){
holder = g[i+1];
g[i]=g[i+1];
g[i+1] = holder;
}
}
}while (i == 1);
for(i = 0;i<4;i++){
printf("%d",g[i]);
}
while (random > 0){
r[i++] = random % 10;
random /=10;
}
do{//took a long long LONG time to get
for(i = 0; i<3;i++){
if(r[i] > r[i+1]){
temp = r[i+1];
r[i]=r[i+1];
r[i+1] = temp;
}
}
}while (i == 1);
for(i = 0;i<4;i++){
printf("%d",r[i]);
}
/* for(digit=0;digit<4;digit++){
for(tmp=guess;tmp>0;tmp/=10){
if(tmp%10==digit){
printf("%d",digit);
g[i++]=digit;
}
}
}
printf("\n");
for(i=0;i<4;i++){
printf("%d",g[i]);
}//just to check
//this is for sorting the random
for(digit=0;digit<4;digit++){
for(tmp=random;tmp>0;tmp/=10){
if(tmp%10==digit){
printf("%d",digit);
r[i++]=digit;
}
}
}
for(i=0;i<4;i++){
printf("%d",r[i]);
}//just to check
*/
//this is for hints
rdig1=r[0];//redefining the random and guess digits so it is easier later
rdig2=r[1];
rdig3=r[2];
rdig4=r[3];
gdig1=g[0];
gdig2=g[1];
gdig3=g[2];
gdig4=g[3];
q = 0;
eq = 0;
lt = 0;
gt = 0;
if (random > 0){//loop that always holds true
if (gdig1 == rdig1){
eq++;
}else if (gdig1 < rdig1){
lt++;
}else if (gdig1 > rdig1){
gt++;
}
if (gdig2 == rdig2){
eq++;
}else if (gdig2 < rdig2){
lt++;
}else if (gdig2 > rdig2){
gt++;
}
if (gdig3 == rdig3){
eq++;
}else if (gdig3 < rdig3){
lt++;
}else if (gdig3 > rdig3){
gt++;
}
if (gdig4 == rdig4){
eq++;
}else if (gdig4 < rdig4){
lt++;
}else if (gdig4 > rdig4){
gt++;
}
}
for (q = 0; q < eq; q++){//counting step for the = <> no problems here^^
putchar('=');
}
for (q = 0; q < lt; q++){
putchar('<');
}
for (q = 0; q < gt; q++){
putchar('>');
}
//everything below is correct do not mess with *******************************************************************************************
} while (gdig1 > 0);//to loop inputs until they input correctly
if ((gdig1 == 0) || (gdig2 == 0) || (gdig3 == 0) || (gdig4 == 0)){//a nested if statement to check each digit if it is a 0
printf("\nYou have entered the Super Secret Code!!!!!\nThe actual passcode is:%d.\n",random);
break;
}
if ((rdig1 == gdig1) && (rdig2 == gdig2) && (rdig3 == gdig3) && (rdig4 == gdig4)){//to skip this codeblock and move onto next
break;
}
} while (((rdig1 != gdig1) && (rdig2 != gdig2) && (rdig3 != gdig3) && (rdig4 != gdig4)));//to loop inputs until they got it
//everything below is correct do not mess with *******************************************************************************************
if ((rdig1 == gdig1) && (rdig2 == gdig2) && (rdig3 == gdig3) && (rdig4 == gdig4)){
printf("\nCorrect Code inputted.");
sleep(1);
printf("\nImplementing unlocking procedures...\n");
for (i=0;i<=4;i++){//for fun cause why not. if you spend hours on code might as well have some fun :)
int p =25*i ;
printf("%d%% complete................\n",p);
sleep(1);
}
printf("Stand back!!! The vault is now opening.\n");
}
return 0;
}
Related
I am new to programming. I am currently taking online lectures quite rigorously and completed a task using Luhn's Algorithm. It is just one script that runs straight through, but for my future-self I want to learn to code more efficiently as projects get bigger.
That is where my problem comes in. I cannot seem to understand how to define or call functions correctly and unable to revise my script into something more "efficient".
(Everything is already submitted and my script completes the task perfectly, according to the bot, so I am not trying to half-arse my work here just to be clear.)
This is the completed script with only the main function that runs straight through and took me about 12-15 hours to get it working without error from the beginning. Everything is written in C
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void)
{
// this grabs the number and verifies the correct amount of digits
int count;
long number = 0;
do
{
number = get_long("Number: ");
count = (number == 0) ? 1 : (log10(number) + 1);
if (count < 13 || count == 14 || count > 16)
{
printf("INVALID\n"); // This is to satisfy the uni. bot command check. Need a EOF for numbers with the wrong amount of digits.
return (0);
}
}
while (count < 13 || count == 14 || count > 16);
//printf("Digits: %i\n", count); // test print for debugging
//This finds the first two digits of input number
long int two = number;
while (two >= 100)
{
two = two / 10;
}
//printf("First two numbers: %li\n", two); // test print for debugging
// verifies card using mod10 (Luhn's)
long sum = 0;
long bigdigit = 0;
//printf("\nLUHN Number: %li\n\n", number); // test print for debugging
if (count == 13 || count == 15)
{
count += 1;
}
for (int i = count; i > 0; i--)
{
if (i % 2 == 0)
{
sum += (number % 10);
}
else
{
bigdigit = (2 * (number % 10));
sum += (bigdigit / 10 + bigdigit % 10);
}
number = (number / 10);
//printf("\nI : %i\n", i); // test print for debugging
//printf("Sum: %li\n", sum); // test print for debugging
//printf("Number: %li\n", number); // test print for debugging
}
if (sum % 10 == 0)
{
printf("VALID\n");
}
else
{
printf("INVALID\n");
return (0);
}
// checks what type of card
if (two == 34 || two == 37)
{
printf("AMEX\n");
return (0);
}
else if (two >= 51 && two <= 55)
{
printf("MASTERCARD\n");
return (0);
}
else if (two >= 40 && two <= 49)
{
printf("VISA\n");
return (0);
}
else
{
printf("INVALID\n");
return (0);
}
}
I was trying to split it into 3 functions of main to call.
long input_number();
bool luhn_check();
void company_check();
I am stuck with the second function and not sure if the third should be a void or not.
"Revised" Script v2
#include <stdio.h>
#include <cs50.h>
#include <math.h>
long input_number(long CCN);
int counter(long CCN, int count);
bool luhn_check(long CCN, int count);
long firsttwo(long CCN, long two);
void card_type(long two);
int main()
{
long CCN = 0;
int count = 0;
long two = 0;
CCN = input_number(CCN);
count = counter(CCN, count);
//printf("CCN: %li\n", CCN); //debugging purposes
//printf("Digits: %i\n", count); //debugging purposes
luhn_check(CCN, count);
two = firsttwo(CCN, two);
//printf("First Two: %li\n", two); //debugging purposes
card_type(two);
}
// this grabs the number and verifies the correct amount of digits
long input_number(long CCN)
{
int count = 0;
do
{
CCN = get_long("Number: ");
count = (CCN == 0) ? 1 : (log10(CCN) + 1);
if (count < 13 || count == 14 || count > 16)
{
//printf("INVALID\n"); // This is to satisfy the uni. bot command check. Need a EOF
//return (0);
}
}
while (count < 13 || count == 14 || count > 16);
return (CCN);
}
int counter(long CCN, int count)
{
do
{
count = (CCN == 0) ? 1 : (log10(CCN) + 1);
}
while (count < 13 || count == 14 || count > 16);
return (count);
}
// verifies card using mod10 (Luhn's)
bool luhn_check(long CCN, int count)
{
long sum = 0;
long bigdigit = 0;
//printf("\nLUHN Number: %ld\n\n", CCN); // test print for debugging
if (count == 13 || count == 15)
{
count += 1;
}
for (int i = count; i > 0; i--)
{
if (i % 2 == 0)
{
sum += (CCN % 10);
}
else
{
bigdigit = (2 * (CCN % 10));
sum += (bigdigit / 10 + bigdigit % 10);
}
CCN = (CCN / 10);
//printf("\nI : %i\n", i); // test print for debugging
//printf("Sum: %li\n", sum); // test print for debugging
//printf("Number: %li\n", CCN); // test print for debugging
}
if (sum % 10 == 0)
{
printf("VALID\n");
return (true);
}
else
{
printf("INVALID\n");
return (false);
}
}
// grabs the first two numbers
long firsttwo(long CCN, long two)
{
two = CCN;
//printf("TWO CCN: %li\n", two); // debugging purposes
while (two >= 100)
{
two = two / 10;
}
return (two);
}
// finds card type and ends
void card_type(long two)
{
if (two == 34 || two == 37)
{
printf("AMEX\n");
//return (0);
}
else if (two >= 51 && two <= 55)
{
printf("MASTERCARD\n");
//return (0);
}
else if (two >= 40 && two <= 49)
{
printf("VISA\n");
//return (0);
}
else
{
printf("INVALID\n");
//return (0);
}
}
I have completed the second version of the script with your suggestions, bar the str of input, I will try to tackle that method in the next version as I have not handled that type yet.
Besides running the program with a string rather than b, is there anything I could have done more efficiently?
Let me start with a few notes on your function input_number:
long input_number()
{
// this grabs the number and verifies the correct amount of digits
int count;
[ .... ]
while (count < 13 || count == 14 || count > 16);
// Once this while loop starts, it will never terminate!
// if count starts at 10 (which is less than 13), the body says "do nothing".
// so count will continue to be unchanged, and the while-loop will continue to run.
return (0); // Code after a return statement will never be reached
// So your printf-statement below will NEVER happen.
// It also seems unlikely you want to return Zero.
// You probably want to return count, or some other value.
printf("Digits: %i\n", count); // test print for debugging
}
I need my program to prompt a user for an input and re-prompt in case the input doesn't follow a credit card format (ex: negative numbers or letters, etc.) and then apply the algorithm to see if the number is a valid credit card number and if yes, whether it's Visa, MasterCard or AmEx.
I know that this question has been answered with different codes on this website, I swear I read everything that I could possibly find (on this site and elsewhere on the net) but I'm having a really hard time understanding the C syntax and I wanted to try to come up with something myself instead of copying bits of codes I don't understand from other answers. If someone can help me out and look at what I've done so far and tell me what I'm doing wrong I would be really grateful. Also, any tips that could help me make sense of the C syntax logic better would be extremely appreciated.
My program is compiling but when I run it it's acting up in a very weird way: when I enter an input sometimes it will say that it is invalid (even if it's a valid number) and sometimes it will just not return anything after I press enter and won't stop running no matter how many times I press the return key.
Here is my code so far:
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void)
{
printf("Please give me your credit card number:\n") ;
long long card_num ;
do
{
card_num = GetLongLong() ;
}
while (card_num < 1 || card_num > 9999999999999999) ;
// Make a copy of the card number to be used and modified throughout the process.
long long temp_num = card_num ;
int digit = 0 ;
int count = 0 ;
int sum_a = 0 ;
int sum_b = 0 ;
// Isolate every digit from the credit card number using a loop and the variable 'digit'.
// Keep track of the amount and position of each digit using variable 'count'.
while (card_num >= 0)
{
digit = card_num % 10 ;
count++ ;
temp_num = (card_num - digit) / 10 ;
break ;
// Apply Luhn's algorithm using two different 'for' loops depending on the position of each digit.
for (count = 0 ; count % 2 == 0 ; count++)
{
sum_a = sum_a + ((card_num % 10) * 2) ;
while ((card_num % 10) * 2 >= 10)
{
sum_a = (sum_a % 10) + 1 ;
}
}
for (count = 0 ; count % 2 != 0 ; count++)
{
sum_b = sum_b + digit ;
}
return sum_a ;
return sum_b ;
return count ;
}
// Checking the validity of the number according to Luhn's algorithm
int total_sum = sum_a + sum_b ;
if (total_sum % 10 != 0)
{
printf("This is an invalid number.\n") ;
}
// If the number entered doesn't have the right amount of digits according
// to variable 'count', declare the number as invalid.
if (count != 13 || count != 15 || count != 16)
{
printf("This is an invalid number.\n") ;
}
// Reset value of variable 'temp_num' and apply calculations that will isolate the first two digits.
// Store the results in a variable 'company_id'.
temp_num = card_num ;
int company_id ;
while (temp_num > 100)
{
temp_num = card_num - (card_num % 10) ;
company_id = temp_num / 10 ;
}
return company_id ;
// Print the type of credit card depending on the company ID and amount of digits.
if (company_id > 50 && company_id < 56 && count == 16)
{
printf("MASTERCARD\n") ;
}
else if ((company_id == 4) && (count == 13 || count == 16))
{
printf("VISA\n") ;
}
else if ((company_id == 34 || company_id == 37) && (count == 15))
{
printf("AMEX\n") ;
}
else
{
printf("This is an invalid number.\n") ;
}
return 0 ;
}
Your answer is a out of order pastiche with sections that don't follow logically from the previous.
Specific issues:
This logic:
if (count != 13 || count != 15 || count != 16)
invalidates every card, the ors (||) should be ands (&&) for this to work.
This loop makes no sense:
while (card_num >= 0)
{
digit = card_num % 10 ;
count++ ;
temp_num = (card_num - digit) / 10 ;
break ;
...
}
The break is unconditional so it exits the loop and ignores the next twenty lines.
You appear to have spliced in subroutines from elsewhere as you call return five times, only the last of which is valid:
return sum_a ;
return sum_b ;
return count ;
return company_id ;
return 0 ;
In several places you use card_num when you should be using temp_num.
You fail to exit the program once you know the card is invalid -- instead you just keep on testing. You fail to acknowledge when a card is valid.
You count the number of digits in the card number but wait until after you run other checks before testing if that digit count was valid or not.
What follows is my rework of your code to address the above and some style issues:
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void)
{
printf("Please give me your credit card number: ") ;
long long card_num = 0LL;
while (card_num < 1LL || card_num > 9999999999999999LL)
{
card_num = GetLongLong();
}
// Make a copy of the card number to be used and modified throughout the process.
long long temp_num = card_num;
// Isolate every digit from the credit card number using a loop and the variable 'digit'.
// Keep track of the amount and position of each digit using variable 'count'.
int count = 0;
while (temp_num > 0LL)
{
temp_num = temp_num / 10LL;
count++;
}
// If the number entered doesn't have the right amount of digits according
// to variable 'count', declare the number as invalid.
if (count != 13 && count != 15 && count != 16)
{
printf("This is an invalid number (# of digits).\n");
return 1;
}
// Reset value of variable 'temp_num' and apply calculations that will isolate the first two digits.
// Store the results in a variable 'company_id'.
temp_num = card_num;
while (temp_num > 100LL)
{
temp_num = temp_num / 10LL;
}
int company_id = temp_num;
// Print the type of credit card depending on the company ID and amount of digits.
if (company_id > 50 && company_id < 56 && count == 16)
{
printf("MASTERCARD\n") ;
}
else if ((company_id == 34 || company_id == 37) && (count == 15))
{
printf("AMEX\n") ;
}
else if ((company_id / 10 == 4) && (count == 13 || count == 16 || count == 19))
{
printf("VISA\n") ;
}
else
{
printf("This card was issued by an unknown company.\n");
}
// Apply Luhn's algorithm.
int sum = 0;
temp_num = card_num;
for (int i = 1; i <= count; i++)
{
int digit = temp_num % 10LL;
if (i % 2 == 0)
{
digit *= 2;
if (digit > 9)
{
digit -= 9;
}
}
sum += digit;
temp_num /= 10LL;
}
// Checking the validity of the number according to Luhn's algorithm
if (sum % 10 != 0)
{
printf("This is an invalid number (Luhn's algorithm).\n");
return 1;
}
printf("This is a valid number.\n");
return 0;
}
This is not a finished program -- there's error checking and other details needed. Rather than summing the digits when a doubled card number is greater than 9, I used the simpler approach of subtracting 9.
Here my solution, this method received the var long credit card number, I hope to be helpful.
void check_card(long n)
{
long temp_n = n;
int count = 2;
while(temp_n > 100)
{
temp_n = temp_n / 10;
count ++;
}
long temp_n2 = n;
int sum = 0;
for (int i = 1; i <= count; i++)
{
int digit = temp_n2 % 10;
if (i%2 == 0)
{
if (digit * 2 > 9)
{
sum += (digit * 2) - 9;
}
else
{
sum += digit * 2;
}
}
else
{
sum += digit;
}
temp_n2 /= 10;
}
bool flag = (sum % 10 == 0) ? true : false;
if (count == 15 && (temp_n == 34 || temp_n == 37) && flag)
{
printf("AMEX\n");
}
else if(count == 16 && (temp_n > 50 && temp_n < 56) && flag)
{
printf("MASTERCARD\n");
}
else if((count == 13 || count == 16) && (temp_n / 10 ==4) && flag)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
I'm a first time programmer trying to complete a simple command line program as part of the first assignment for an online course I am taking, but I seem to have hit a roadblock that I can't figure out with GDB or my own research.
After hours of rewrites, and hours of debugging, I finally got the code below to compile. The program is supposed to take a credit card number as an input, and then check whether it's valid per the specifications of the assignment. I used a test number from here: PayPal Test Credit Cards
The odd thing is, when I enter an AMEX card number, it correctly produces the text "AMEX", but when I try a Visa or a Master Card, it prints "INVALID".
In GDB I broke at the Verify function and it seems to incorrectly skip these two if/else if statements without proceeding to the Checksum function even though conditions appear to be met.
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.
...
The AMEX line of code that correctly executes is:
else if (firstDigit == 3 && secondDigit == (4 | 7) && totalDigits == 15 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid American Express.
The arguments for all three lines seem to be formatted exactly the same. That is far as I could get in GDB though. I would print totalDigits, firstDigit, and secondDigit in GDB right before stepping through the above two non-executing lines and everything looked correct. So I'm stumped, why is the AMEX line executing, but not the others?
Thanks in advance everyone. This is the first program after hello.c that I've tried to write, so I am open to absolutely any criticism or suggestions if it looks like I'm doing something weird/wrong.
Full code:
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;
}
}
Your first problem is here:
if (firstDigit == 4 && totalDigits == (13 | 16) && ...
You need to write:
if (firstDigit == 4 && (totalDigits == 13 || totalDigits == 16) && ...
Your first check is looking for 0x1D == 29 as the number of digits (because, as paisanco points out in a comment, the | operator is the bitwise OR operator), and no credit card needs 29 digits (yet, and not for a long time to come). Note the extra parentheses for clarity and accuracy. Don't mess around risking removing them — the code won't work properly again. And in general, be explicit if your condition has both && and || operators and use parentheses to group terms explicitly.
You have similar problems elsewhere. As it happens, (4 | 7) is the same value as 7, so the condition works when the second digit is 7 (but not when it is 4). But it doesn't mean what you intended it to mean.
Computer languages don't work the same as human languages. Get used to writing out the condition somewhat more verbosely. Some other languages provide shorthands for these conditions; C is not such a language.
I'm reading a book on C programming and try to do the exercises:
Write a program that prints a horizontal histogram consisting of stars(*). One star for every number there can be in the interval 0 ... 70.
#include <stdio.h>
void draw_stars(int number_of_stars) {
int counter = 0;
for(counter = 0; counter < number_of_stars; counter++) {
printf("*");
}
printf("\n");
}
int main(void) {
int counter1, counter2, ones, tens, zero, one, two, three, four, five, six, seven, eight, nine = 0;
for(tens = 0; tens < 7; tens++) {
if(tens == 0)
zero = zero + 1;
if(tens == 1)
one = one + 10;
if(tens == 2)
two = two + 10;
if(tens == 3)
three = three + 10;
if(tens == 4)
four = four + 10;
if(tens == 5)
five = five + 10;
if(tens == 6)
six = six + 10;
if(tens == 7)
seven = seven + 10;
for(ones = 0; ones < 9; ones++) {
if(ones == 0)
zero++;
if(ones == 1)
one++;
if(ones == 2)
two++;
if(ones == 3)
three++;
if(ones == 4)
four++;
if(ones == 5)
five++;
if(ones == 6)
six++;
if(ones == 7)
seven++;
if(ones == 8)
eight++;
if(ones == 9)
nine++;
}
}
draw_stars(zero);
draw_stars(one);
draw_stars(two);
draw_stars(three);
draw_stars(four);
draw_stars(five);
draw_stars(six);
draw_stars(seven);
draw_stars(eight);
draw_stars(nine);
}
For some reason my program enters a infinite loop printing stars. But I can't find out why?
I haven't been able to come up with any other solution, but I still think it's ugly and bloated. How would a real C programmer solve this?
Edit:
After reading and understanding the chapter about arrays in the book, I was able to write a more clean version of the program. I'm posting it here as it might help other beginners understand the use of arrays. Writing an identical program in terms of output, but using different functionality of the language is a great learning experience.
#include <stdio.h>
#define TENS 7
void draw_stars(int stars) {
int star_counter = 0;
for (star_counter = 0; star_counter < stars; star_counter++)
printf("%c", '*');
}
int main(void) {
int number_array[10];
int tens_counter, ones_counter;
for (ones_counter = 0; ones_counter < 10; ones_counter++)
number_array[ones_counter] = 0;
for (tens_counter = 0; tens_counter < TENS; tens_counter++) {
if (tens_counter != 0)
number_array[tens_counter] += 10;
else
number_array[tens_counter] += 1;
for (ones_counter = 0; ones_counter < 10; ones_counter++)
number_array[ones_counter]++;
}
for (ones_counter = 0; ones_counter < 10; ones_counter++) {
draw_stars(number_array[ones_counter]);
printf("\n");
}
}
Initialize all variables:
int counter1=0, counter2=0, ones=0, tens=0, zero=0, one=0..
BTW, for better performance,
replace if with else if except the first one in the block. Why do you want to check all if conditions when you already know only one is true?
FYI, when a condition is true in Else if, all other ifs are skipped.
If you wanted to initialize all ints to zero, you should write:
int counter1=0, counter2=0, ...
Now only nine is init by 0, other variables contain rubbish - arbitrary values.
in main() you have to initialize all variable with zero like
int counter1=0,counter2=0 and so on
otherwise it take garbage value and perform operation with those values and then output will be like
********
*****************
*****************
*****************
*****************
*****************
*****************
*******
*******
I need compute the first 100 prime numbers, but in the output i got "9" and other in my numbers....................... i want compute the first 100 prime numbers
{
bool prime; int start, new, kor,k, i,gg;
start=1;
k=1 ;
gg=0;
do
{
if (start < 2) {new = 2;}
if (start == 2) {new = 3;}
if (start > 2) {
if ((new % 2) == 0)
new--;
do {
prime = true;
kor=sqrt(new);
new+=2;
for (i=3;prime&& (i<=kor); i+=2) {
if (new % i == 0)
prime=false;}
} while (!prime) ;
}
gg++;
printf("%d->%d\n",gg, new);
k++;
start++;
continue;
}
while (k<101);
}
With
if (start < 2) {new = 2;}
if (start == 2) {new = 3;}
you have special cases the first and second numbers.
Next time round the do...while loop we skip the for loop because kor is 1, thereby printing 5. Which we didn't check, so perhaps we just got lucky. Smells like we don't check far enough.
Next time, after
kor=sqrt(new1); new1+=2;
kor is 2, so again we don't do the for loop, and print 7. Next time we have the same situation. kor is still 2 so you get 9.
I think if you switch the new+=2 to before the kor=sqrt(1); it will work.
Once you are in this part, you don't need to check if something is even, since you always add 2 to an odd number.
BTW Why does it say continue as the last thing in the loop?
This might be better (I took the liberty of putting it in a function):
void find_primes()
{
bool prime; int start, new, kor,k, i,gg;
start=1; k=1 ;gg=0;
do
{
if (start < 2) {new = 2;}
if (start == 2) {new = 3;}
if (start > 2) {
do {
prime = true;
new+=2;
kor=sqrt(new);
for (i=3;prime&& (i<=kor); i+=2) {
if (new % i == 0)
prime=false;
}
}
while (!prime) ;
}
gg++; printf("%d->%d\n",gg, new);
k++;
start++;
}
while (k<101);
}
I don't know what language you're programming in, so I'm taking a guess at this (I can't comment yet)-
Are you getting all odd numbers as output in your answer? 9, 11, 13, 15...
It seems that you are printing out all values of 'new', regardless of whether prime is true or not. Maybe you should put a
if (prime) {
printf("%d->%d\n",gg, new);
}
there
here is an example program from:
http://www.programmingsimplified.com/c/source-code/c-program-for-prime-number
note: 1 is not a prime number, see:
http://primes.utm.edu/notes/faq/one.html
#include<stdio.h>
int main()
{
int n, i = 3, count, c;
printf("Enter the number of prime numbers required\n");
scanf("%d",&n);
if ( n >= 1 )
{
printf("First %d prime numbers are :\n",n);
printf("2\n");
}
for ( count = 2 ; count <= n ; )
{
for ( c = 2 ; c <= (i - 1) ; c++ )
{
if ( i%c == 0 ) break;
}
if ( c == i )
{
printf("%d\n",i);
count++;
}
i++;
}
return 0;
}