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


Groups > comp.lang.c > #69903

Re: A finalized program

From Ben Bacarisse <ben.usenet@bsb.me.uk>
Newsgroups comp.lang.c
Subject Re: A finalized program
Date 2015-09-08 14:45 +0100
Organization A noiseless patient Spider
Message-ID <87r3m9nhwp.fsf@bsb.me.uk> (permalink)
References <d93ca264-e41a-4f82-8c09-cd87731b2eed@googlegroups.com> <0b40a48e-3d88-46dd-adf2-275a33a87f65@googlegroups.com>

Show all headers | View raw


Alla _ <modelling.data@gmail.com> writes:

> On Tuesday, September 8, 2015 at 3:13:57 PM UTC+4, Alla _ wrote:
>> Hello!
>> 
>> First of all, I want to say that I can't
>> believe that I did "cobbled together" a
>> program, which I consider to be a difficult 
>> one for someone like me. I am very thankful 
>> for everyone who has helped me with all previous
>> programs and with the beginning part of this 
>> program: if not your help, I wouldn't make such
>> progress, seriously. 
>> 
>> Here is the program. Of course, I would love
>> to see your comments and suggestions, as well
>> as any nitpicking; any would be of a great 
>> help. But, please, remember that I am at the 
>> initial stage, hence I can understand only 
>> basics for now :)
>> 
>> Also, of course, I have to revise this 
>> program to add functions, but this topic
>> is still nebulous to me.
>> 
>> 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)
>>     {        
>>         for (i = (strlen(card_number) - 2); i >= 0; i -= 2)
>>         {
>>             number = (card_number[i] - '0') * 2;
>>             
>>             if (number >= 0 && number <= 9)
>>             {
>>                 sum1 += number;
>>             }
>>             
>>             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');
>>         }
>>         
>>         sum = sum1 + sum2 + sum3;
>>         
>>         if (sum % 10 == 0)
>>         {
>>             if (strlen(card_number) == 15)
>>                printf ("It's a valid AMEX\n");
>>             
>>             else if (strlen(card_number) == 16)
>>                printf ("It's a valid MASTERCARD or VISA\n");
>>             
>>             else if (strlen(card_number) == 13)
>>                printf ("It's a valid VISA\n");
>>             
>>             else
>>                 printf ("Card of an unknown card issuer\n");
>>         }
>>         
>>         else
>>             printf ("Sorry, the card number failed the test\n");
>>     }
>>     
>>     printf ("\n");
>>     return 0;
>> }
>> 
>> II version with switch statement at the end (though
>> switch statement doesn't completely serve the purpose):
>> 
>> #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)
>>     {        
>>         for (i = (strlen(card_number) - 2); i >= 0; i -= 2)
>>         {
>>             number = (card_number[i] - '0') * 2;
>>             
>>             if (number >= 0 && number <= 9)
>>             {
>>                 sum1 += number;
>>             }
>>             
>>             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');
>>         }
>>         
>>         sum = sum1 + sum2 + sum3;
>>         
>>         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:
>>                     break;
>>             }  
>>         }
>>         
>>         else
>>             printf ("Sorry, the card number failed the test\n");
>>     }
>>     
>>     printf ("\n");
>>     return 0;
>> }
>
> Although I've written this, I still think the 
> function strlen is not totally clear to me.

That's not surprising because it brings up oe the most surprising things
about C (though not directly related to your question below).

> In for (i = (strlen(card_number) - 2); i >= 0; i -= 2)
> I subtract 2 from strlen(card_number) to start the loop
> for the second digit from the end. I come up with this
> minus 2 after a few tests, and this tells me that 
> strlen computes the number of characters from 0 to n, including; 
> therefore strlen should give the length that is 1 more than
> the actual length of the string.

The user enters 16 digits: 0123456789012345.  strlen will report 16 --
the actual length.  These 16 characters are indexed from 0 to 15
inclusive so to get the first you use card_number[0] and to get the last
card_number[15].  The last-but-one is card_number[14] -- that's
strlen(card_number) - 2.

> But both in switch and if statements, I use the exact 
> length of the string (not 17, if the actual length is 16)
> to get the right answer. When I tested with strlen which 
> is n + 1, I got wrong answers. 
>
> What is the math behind strlen?

I think you just forgot that arrays start at 0 so the characters in a
string run from s[0] to s[len - 1].

But there is a problem with the way you use strlen.  It's a function
that returns an unsigned value -- not an int (specifically a value of
type size_t used in C to represent sizes of things).  When you do
arithmetic on unsigned types you can't get a signed result[1].  What
happens is that the value wraps round modulo one more than the largest
value that can be stored.  (If you know how machines represent numbers
you'll see that this is the "natural" thing to do.)  As a result, if
strlen returns a number less than 2, your subtraction will produce a
very large number indeed.  Now you may wonder why you program does not
then go haywire trying to get at millions of non-existent elements of
the card_number array?  Well, it's because you put the number back into
an int variable (i).  On most systems that converts the very large
number back into a small negative one (exactly the one you expect in
most cases).

You may ask why is the a problem then?  Well the C language allows
implementations to raise an error when that conversion back to int is
done.  You probably wont find such a machine where this actually happens
but its better to write code that will work everywhere.

[1] That's not always strictly true, but you really don't care about the
details.

-- 
Ben.

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