Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #69901

Re: A finalized program

From jt@toerring.de (Jens Thoms Toerring)
Newsgroups comp.lang.c
Subject Re: A finalized program
Date 2015-09-08 13:41 +0000
Organization Freie Universitaet Berlin
Message-ID <d586scFdva0U1@mid.uni-berlin.de> (permalink)
References <d93ca264-e41a-4f82-8c09-cd87731b2eed@googlegroups.com>

Show all headers | View raw


Alla _ <modelling.data@gmail.com> wrote:
> The task was to:
> 1) Get the card number from the user.

> 2) Multiply every other digit by 2, 
> starting with the number's second-to-last digit, 
> and then add those products' digits together.

> 3) Add the sum to the sum of the digits that 
> weren't multiplied by 2.

> 4) If the total's last digit is 0 (or, put more 
> formally, if the total modulo 10 is congruent to
> 0), the number is valid.

> 5) If the card is valid, print that it's a valid 
> card and the name of the issuer.

> I version: 

> #include <stdio.h>
> #include <string.h>

> int main(void)
> {
>     char card_number[17];
>     int i, number, digit, sum;
>     int sum1 = 0, sum2 = 0, sum3 = 0;
>     
>     printf ("Please, enter your card number:  \n");
>     
>     if (scanf ("%s", card_number) == 1)

Here's a potential problem: what happens if the user enters
a number that's longer than 16 digits? In that case scanf()
will try to write all of them into the 'card_number' buffer
and in the process write past the end of it. And that, of
course, is a rather evil thing to do - it's now completely
unclear what the program will do. It might even seem to work
correctly.

So you must find some way to stop scanf() from reading more
than 16 characters. The simplest way to do that is to pass
the maximum length with the "%s" format specifier, i.e.

     if ( scanf( "16%s", card_number ) == 1 )

With this is will never attempt to read more than a 16
characters.

>     {        
>         for (i = (strlen(card_number) - 2); i >= 0; i -= 2)
>         {
>             number = (card_number[i] - '0') * 2;

>             
>             if (number >= 0 && number <= 9)

I guess, since you multiplied by two, this should be

             if ( number >= 0 && number <=  18 )


>             {
>                 sum1 += number;
>             }
>             

What now follows doesn't seem to make too much sense.
Obviously, the user must have entered something that
wasn't a digit. But you now try to make something out
of it, but I guess it should be treated as an invalid
card number. And here you then also handle those cha-
racters that had a higher number representation than
'9' but not those with one less than '0'.

>             if (number > 9)
>             {
>                 while (number > 0)
>                 {
>                     digit = number % 10;
>                     sum2 += digit;
>                     number /= 10;
>                 }
>             }
>         }
>         
>         for (i = (strlen(card_number) - 1); i >= 0; i -= 2)
>         {
>             sum3 += (card_number[i] - '0');

And here you don't even attempt to test if what the user
entered was a digit...

>         }

Here's an idea how it could done a bit differently:

    char card_number[ 17 ];
    printf( "Enter card number: " );
    while ( ! (    scanf( "%16[0-9]", card_number ) == 1
                && getchar( ) == '\n' ) )
    {
        printf( "Not a card number, please re-ennter it: " );
        while ( getchar( ) != '\n' )
            /* empty */ ;
    }

The "%16[0-9]" format specifier tells scanf() to read in only
digits (and 16 at most). The additional test for '\n' makes
sure that this was all the user entered and scanf() didn't
stop because it found something that was not a digit (or
more than 16 digits). In the loop there's a second while
loop to remove everything from the input buffer the user
typed (which obviously wasn't something that could appear
in a card number).

The summing up could also simplified a bit:

    int sum = 0;
    size_t i = strlen( card_number );
    while ( i > 0 )
    {
        sum += card_number[ --i ] - '0';
        if ( i > 0 )
            sum += 2 * card_number[ --i ] - '0';
    }

You actually don't need two loops, a single one will do.
Here no tests if what the user typed was all digits, that
has all been done by scanf().

>         if (sum % 10 == 0)
>         {
>             switch (strlen(card_number))
>             {
>                 case 15:
>                     printf ("It's a valid AMEX\n");
>                     break;
>                 case 16:
>                     printf ("It's a valid MASTERCARD or VISA\n");
>                     break;
>                 case 13:
>                     printf ("It's a valid VISA\n");
>                     break;
>                 default:

Here you should also have (as in your other version) some-
thing like 

                      printf( "Vaild card from unknown card issuer\n" );

>                     break;
>             }  
>         }
>         
>         else
>             printf ("Sorry, the card number failed the test\n");
>     }
>     
>     printf ("\n");
>     return 0;
> }

There's one more snag though: if the user just enters '0'
this will be seen as a valid card number, but which it
probably isn't. I guess the specifications are a bit
incomplete, there rather likely is a lower bound for
the length of a card number.

                         Regards, Jens
-- 
  \   Jens Thoms Toerring  ___      jt@toerring.de
   \__________________________      http://toerring.de

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-08 04:13 -0700
  Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-08 04:19 -0700
    Re: A finalized program fir <profesor.fir@gmail.com> - 2015-09-08 04:30 -0700
    Re: A finalized program Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-08 14:45 +0100
      Re: A finalized program Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-08 08:29 -0700
      Re: A finalized program Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-08 08:52 -0700
        Re: A finalized program Martin Shobe <martin.shobe@yahoo.com> - 2015-09-08 13:01 -0500
        Re: A finalized program Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-08 21:00 +0100
          Re: A finalized program Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-08 13:33 -0700
            Re: A finalized program Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-09 00:28 +0100
  Re: A finalized program Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-08 14:26 +0100
    Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-08 06:42 -0700
      Re: A finalized program Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-08 20:50 +0100
        Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 01:47 -0700
  Re: A finalized program jt@toerring.de (Jens Thoms Toerring) - 2015-09-08 13:41 +0000
    Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-10 01:31 -0700
      Re: A finalized program jt@toerring.de (Jens Thoms Toerring) - 2015-09-10 10:39 +0000
        Re: A finalized program David Thompson <dave.thompson2@verizon.net> - 2015-09-20 18:35 -0400
    Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-10 01:33 -0700
    Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-10 10:16 -0700
      Re: A finalized program bartekltg <bartekltg@gmail.com> - 2015-09-10 20:08 +0200
        Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 02:05 -0700
          Re: A finalized program Richard Heathfield <rjh@cpax.org.uk> - 2015-09-11 10:17 +0100
            Re: A finalized program Richard Heathfield <rjh@cpax.org.uk> - 2015-09-11 10:19 +0100
            Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 02:28 -0700
            Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 02:29 -0700
        Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 02:19 -0700
          Re: A finalized program Richard Heathfield <rjh@cpax.org.uk> - 2015-09-11 10:23 +0100
            Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 02:33 -0700
              Re: A finalized program Keith Thompson <kst-u@mib.org> - 2015-09-11 14:11 -0700
                Re: A finalized program jt@toerring.de (Jens Thoms Toerring) - 2015-09-11 21:39 +0000
          Re: A finalized program bartekltg <bartekltg@gmail.com> - 2015-09-11 12:49 +0200
      Re: A finalized program Richard Heathfield <rjh@cpax.org.uk> - 2015-09-10 23:31 +0100
        Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 02:15 -0700
      Re: A finalized program jt@toerring.de (Jens Thoms Toerring) - 2015-09-10 22:37 +0000
        Re: A finalized program Richard Heathfield <rjh@cpax.org.uk> - 2015-09-10 23:47 +0100
          Re: A finalized program jt@toerring.de (Jens Thoms Toerring) - 2015-09-11 10:18 +0000
        Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 01:07 -0700
        Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 02:14 -0700
          Re: A finalized program jt@toerring.de (Jens Thoms Toerring) - 2015-09-11 10:10 +0000
            Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 04:19 -0700
  Re: A finalized program Barry Schwarz <schwarzb@dqel.com> - 2015-09-08 15:53 -0700
  Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 04:27 -0700
    Re: A finalized program bartekltg <bartekltg@gmail.com> - 2015-09-11 14:05 +0200
  Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 04:42 -0700
    Re: A finalized program bartekltg <bartekltg@gmail.com> - 2015-09-11 14:15 +0200
      Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 05:50 -0700
        Re: A finalized program bartekltg <bartekltg@gmail.com> - 2015-09-11 15:00 +0200
      Re: A finalized program Alla _ <modelling.data@gmail.com> - 2015-09-11 05:50 -0700
    Re: A finalized program Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-11 13:46 +0100
      Re: A finalized program Richard Heathfield <rjh@cpax.org.uk> - 2015-09-11 14:19 +0100

csiph-web