LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Basic C programming question (https://www.linuxquestions.org/questions/programming-9/basic-c-programming-question-4175719828/)

GazL 12-19-2022 11:05 AM

Seems most of them make the same mistake that Sundial was warning about: a long is not guaranteed to be large enough on all platforms. unsigned long long should be good for 19 digits however, but as Sundial says, why limit yourself: process the number as a string.

lxs602 02-06-2024 02:30 PM

Long overdue, but thanks.

sundialsvcs 02-06-2024 10:34 PM

Also: when this is not “a learning exercise,” remember that there are many contributed libraries of software … for every programming language that exists … where other(!) people have confronted these “problems that we all have,” and solved them very well. Including all(!) variations of “credit-card number validation.”

It’s very important to realize, when you are first “learning to program in [X],” that today you are not “alone.” Extremely the opposite. Therefore, when you confront any problem, your first assumption should be that someone else has already done it. (And that you can freely “sneak a peek” at their source code. In due time, you might make your own contribution …)

lxs602 04-23-2024 03:23 PM

Thanks. I was trying not to, but probably better than becoming frustrated.

murugesandins 04-23-2024 08:55 PM

Quote:

Originally Posted by lxs602 (Post 6398133)
I also tried using gdb, but it gave an error to do with get_long being not declared.

I faced the same issue after copy and compiling your code.c at localhost using gcc.exe (CYGWIN_NT)
Initially I was not having libcs50 library
Downloaded https://github.com/cs50/libcs50/arch...gs/v11.0.2.zip
Code:

$ unzip.exe libcs50-11.0.2.zip >/dev/null 2>&1
$ cd libcs50-11.0.2
$ make
make: Nothing to be done for 'all'.
$ /usr/bin/cp -i "Makefile" "Makefile.Original"
$# I modified Makefile related to CYGWIN
$ diff Makefile Makefile.Original
17c17
< OS := $(shell /usr/bin/uname | /usr/bin/sed "s/-[0-9]*\.[0-9]-[0-9]*//;")
---
> OS := $(shell uname)
19,24d18
< # CYGWIN_NT
< ifeq ($(OS),CYGWIN_NT)
<      LIB_BASE := $(BASENAME).so
<      LIB_MAJOR := $(BASENAME).so.$(MAJOR_VERSION)
<      LIB_VERSION := $(BASENAME).so.$(VERSION)
<      LINKER_FLAGS := -Wl,-soname,$(LIB_MAJOR)
26c20
< else ifeq ($(OS),Linux)
---
> ifeq ($(OS),Linux)
$ make
#...
install -m 644 src/cs50.h build/include
mv libcs50.so.11.0.2 libcs50.so libcs50.a build/lib
$ /usr/bin/find ./ -type f -name cs50.h
$ mv ./build/include/cs50.h /usr/include/
$ find ./ -type f -name "*.a" -exec grep -l get_long {} \;
./build/lib/libcs50.a
$ find ./ -type f -name "*.so*" -exec grep -l get_long {} \;
./build/lib/libcs50.so.11.0.2
$ mv ./build/lib/libcs50.so.11.0.2 ./build/lib/libcs50.a /usr/lib
$ /usr/bin/gcc.exe -I. -g -Wall 4175719828.c -o ./a.out -lcs50

Inside checkfunction
if( 0 == x || 0 > i )
{
break;
}
to prevent core dump issue
I have taken base version from https://github.com/jhustles/c_verify...editCardType.c
Code:

#include <cs50.h>
#include <math.h>
#include <stdio.h>
int main(void)
{
        // Always initialize the variable
        long DebitCreditCardNum = 0;
        int sumOfProductDigits = 0;
        int sumOfNonProductDigits = 0; // sum of digits that are not products
        int checkSum = 0;
        long NumModulusTen = 0;
        long SecondModulusTen = 0;
        // Prompt user for credit card input.
        do
        {
                DebitCreditCardNum = get_long( "Number: " );
                // printf( "%li\n", DebitCreditCardNum);
        }
        while( 0 > DebitCreditCardNum );
        sumOfProductDigits = 0;
        sumOfNonProductDigits = 0;
        long ccNumbers1 = DebitCreditCardNum; // Used for checkSum
        long ccNumbers2 = DebitCreditCardNum; // Used for card validation
        while( 0 < ccNumbers1 )
        {
                NumModulusTen = ccNumbers1 % 10; // out: 4
                sumOfNonProductDigits += NumModulusTen; // add 4
                // printf( "Adding %li\n to sumOfNonProductDigits\n", NumModulusTen);
                ccNumbers1 = ccNumbers1 - NumModulusTen; // minus the last digit
                ccNumbers1 = ccNumbers1 / 10; // reduce by one last digit by dividing by 10
                // printf( "Updated ccNumbers1 after is: %li\n", ccNumbers1);
                // printf( "###########################\n" );
                // Second Number to iterate thru
                SecondModulusTen = ccNumbers1 % 10; // out: 1
                // printf( "Here's SecondModulusTen: %li\n \n", SecondModulusTen);
                // printf( "Sum Of Product Digits: %i\n \n", sumOfProductDigits);
                // printf( "Sum Of Non-Product Digits: %i\n \n", sumOfNonProductDigits);
                ccNumbers1 = ccNumbers1 - SecondModulusTen;
                ccNumbers1 /= 10;
                if( 9 < SecondModulusTen * 2 ) // if there's two digits you'll have to add each digit
                {
                        // Product result is double digits. Repeat the same thing to split numbers
                        // and reduce the ccNumbers1
                        SecondModulusTen = SecondModulusTen * 2;
                        int numSlice = SecondModulusTen % 10; // split by getting the last digit
                        sumOfProductDigits += numSlice;
                        sumOfProductDigits += ((SecondModulusTen - numSlice) / 10); // add to products sum
                }
                else
                {
                        // multiply the digit by 2 and add to sumOfProductDigits
                        SecondModulusTen = SecondModulusTen * 2;
                        sumOfProductDigits += SecondModulusTen;
                }
        }
        checkSum = sumOfProductDigits + sumOfNonProductDigits;
        // printf( "CHECK SUM: %i\n", checkSum);
        // Algorithm to check if card is valid:
        if( 0 == checkSum % 10 )
        {
                bool amex = false;
                bool mastercard = false;
                bool visa = false;
                amex =
                        (ccNumbers2 >= 340000000000000 && ccNumbers2 < 350000000000000) ||
                        (ccNumbers2 >= 370000000000000 && ccNumbers2 < 380000000000000);
                mastercard =
                        (ccNumbers2 >= 5100000000000000 && ccNumbers2 < 5600000000000000);
                visa =
                        (ccNumbers2 >= 4000000000000 && ccNumbers2 < 5000000000000) ||
                        (ccNumbers2 >= 4000000000000000 && ccNumbers2 < 5000000000000000);
                if(amex)
                {
                        printf( "AMEX\n" );
                }
                else if(mastercard)
                {
                        printf( "MASTERCARD\n" );
                }
                else if(visa)
                {
                        printf( "VISA\n" );
                }
                else
                {
                        printf( "%lu INVALID_NUMBER\n", DebitCreditCardNum );
                }
        }
        else
        {
                printf( "%lu INVALID NUMBER\n", DebitCreditCardNum );
        }
        return 0;
}
/*
01. Always initialize variables
02. Alwayse beter to write return/return0 based on the functions.
03. Replace:
        while (DebitCreditCardNum < 0);
        ...
        if
        ...
        else if
        ...
        for
With:
        while( 0 > DebitCreditCardNum );
        ...
        if
        ...
        else if
        ...
        for
Reason: new programmers may assign using:
        while( DebitCreditCardNum = 0 );
I have taken following ATM card numbers from internet images:
$ ./a.out
Number: 5333619503715702
MASTERCARD
$ a.out
Number: 5555555555554444
MASTERCARD
$ a.out
Number: 5454545454545454
MASTERCARD
$ a.out
Number: 4444333322221111
VISA
*/

$ mv verifyCreditCardType.c ValidateCardType.c
$ /usr/bin/gcc.exe -g -Wall ValidateCardType.c -o ./a.out -lcs50


All times are GMT -5. The time now is 03:52 PM.