Thread: [HELP] ISBN Check Digit

  1. #1
    Registered User
    Join Date
    Apr 2009
    Posts
    29

    [HELP] ISBN Check Digit

    Code:
    #include <iostream.h>
    #include <conio.h>
    #include <stdio.h>
    #include <string.h>
    
    int main()
    
    {
        char cISBN[10];
        int i,iLen,iNNF,iISBN[9],iTotal,iCheck;
        
        for(i=0;i<10;i++)
        {
                         cISBN[i]='\0';
        }
                         
                         printf("Enter ISBN ");
                         gets(cISBN);
                         iLen=strlen(cISBN);
                         
                         if(iLen!=9)
                         {
                                    printf("ISBN length error ");
                         }
                                    
                                    else
                                    {
                                        iNNF=0;
                                        for(i=0;i<iLen&&iNNF==0;i++)
                                        {
                                                                   if((cISBN[i]<0)||(cISBN[i]>9))
                                                                   {
                                                                                      printf("ISBN numerical error ");
                                                                                      iNNF=1;
                                                                   }
                                                                                      
                                                                                      else
                                                                                      {
                                                                                          iTotal=0;
                                                                                          iISBN[i]=cISBN[i]-48;
                                                                                          iTotal=iISBN[i]*(i+1);
                                                                                      }
                                        }
                                    }
                                                                                          
                                                                                          iCheck=0;
                                                                                          iCheck=iTotal%11;
                                                                                          cout<<(iCheck);
                                                                                          
                                                                                          getch();
    }
    Error 1 (gone): if(cISBN[i]<0||>9) /*expected primary-expression before '>' token*/
    thanks Adak and MK27.

    Error 2:
    input 013190190
    output 7 (should be)

    But it gave me "ISBN numerical error 10" or "ISBN length error 10" as output instead, I don't know where the 10 came from, try run it...
    Last edited by Dakaa; 04-20-2009 at 04:26 AM.

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    if(cISBN[i]<0||>9) /*expected primary-expression before '>' token*/


    if(cISBN[i] < 0 || cISBN[i] > 9) {

    //etc.

    The error message said it all.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    gcc will recommend this (parantheses around truth test); it makes code more readable, it makes the issue of this thread clear, and there may be further reasons:
    Code:
    if((cISBN[i] < 0) || (cISBN[i] > 9)) {
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Registered User
    Join Date
    Apr 2009
    Posts
    29
    Thanks alot, here comes another error, help please?

    input 013190190
    output 7 (should be)

    But it gave me "ISBN numerical error 10" or "ISBN length error 10" as output instead, I don't know where the 10 came from, try run it...
    Last edited by Dakaa; 04-20-2009 at 04:26 AM.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You have a char array with 10 elements.

    You're using gets() to put in 10 char's.

    Which leaves the newline still in the keyboard buffer, waiting to much up the next number. Perhaps coincidentally (perhaps not), a line feed char is ascii value 10!

    I would add a getchar() after the gets, to pull the newline char off the buffer, and then if your problem is still present.

    Your wild indentation makes your code very much a PITA, to follow. Every opening brace, should have a matching closing brace *directly below it* (in the same vertical column).

    This is dreadful, frankly:

    Code:
                 }
                 }
                 }
    Last edited by Adak; 04-19-2009 at 07:10 PM.

  6. #6
    Registered User
    Join Date
    Apr 2009
    Posts
    29
    Which leaves the newline still in the keyboard buffer, waiting to much up the next number. Perhaps coincidentally (perhaps not), a line feed char is ascii value 10! I still don't understand that, please explain?

    After replacing gets() with getchar(), it says

    Line 272 too many arguments to function `int getchar()'
    Line 18 at this point in file

    Okay, I changed the positions of the closing brackets thingy, so it's much easier to read.
    Last edited by Dakaa; 04-20-2009 at 04:27 AM.

  7. #7
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Dakaa View Post
    Which leaves the newline still in the keyboard buffer, waiting to much up the next number. Perhaps coincidentally (perhaps not), a line feed char is ascii value 10! I still don't understand that, please explain?
    To make a long story short, stdin input is up to AND INCLUDING the newline character, so if you call on stdin, that's what gets put in the stdin buffer. If you do not read everything that's in there out, the stdin file pointer is set to wherever you left off.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by Dakaa View Post
    Which leaves the newline still in the keyboard buffer, waiting to much up the next number. Perhaps coincidentally (perhaps not), a line feed char is ascii value 10! I still don't understand that, please explain?

    replaced gets() with getchar()

    Line 272 too many arguments to function `int getchar()'
    Line 18 at this point in file

    k, i changed the positions of the closing brackets thingy.
    Good, because I'm not checking code that looks like Bugs Bunny wrote it.

    Say you have a gets(); taking a string, into your char array.

    The string is 10 char's long, and your char array is also 10 elements long. Note that there is NO ROOM for the newline which is in the keyboard buffer, and generated every time you hit the Enter key.

    Say I enter this: 0123456789 - OK, that's 10 digits, and it all fits into the char array[], but what you don't see is this:

    0123456789\n - which is what's really there.

    So the newline char '\n' is left in the keyboard buffer. The next input will have to deal with it - by ignoring it and skipping over it (like scanf() will do for a number), or accept that newline char, as your intended input, like scanf() will do when it's expecting a char (%c) format.

    The newline char is what is written to the file, *BUT* when the file is opened for input as a text file, the OS will change that newline, into *TWO* chars - a line feed (ascii 10), and a Carriage Return(ascii 13).

    In binary file mode, that change of the newline, does not occur.

    Problems with newlines are probably the most common problem we see on this forum. I don't know if it's your problem, because your code was so MICKY MOUSE, in format, I started cursing at it, and quit.

    I'll try and look it through, again.

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I adjusted your program to something I could follow, and that compiles:

    Code:
    
    //#include <iostream.h>  //
    #include <conio.h>
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
       char cISBN[10] = {"013190190"};
       int i,iLen,iNNF,iISBN[9],iTotal,iCheck;
        
    /* for(i=0;i<10;i++)
       {
          cISBN[i]='\0';
       }
                       
       printf("Enter ISBN ");
       gets(cISBN);
    */
       iLen=strlen(cISBN);
       if(iLen!=9)
       {
          printf("ISBN length error ");
       }
                                    
       else
       {
          iNNF=0;
          for(i=0;i<iLen&&iNNF==0;i++)
          {
             if((cISBN[i] - '0'< 0)||(cISBN[i] - '0'> 9))
             {
                printf("ISBN numerical error ");
                iNNF=1;
             }
             else
             {
                iTotal=0;
                iISBN[i]=cISBN[i]-48;
                iTotal += iISBN[i]*(i+1);
             }
          }
       }
       printf("iTotal: %d", iTotal);
       getch();
       return 0;
    }
    /*
    Error 1 (gone): if(cISBN[i]<0||>9) /*expected primary-expression before '>' token*/
    thanks Adak and MK27.
    
    Error 2:
    1*(0)+2*(1)+3*(3)+4*(1)+5*(9)+6*(0)+7*(1)+8*(9)+9* (0)=139
    139/11=12 rem 7
    139=7(mod11)
    Check digit is 7.
    
    my horrible code
    input 013190190
    output 7
    
    it gave me "ISBN numerical error 10" instead of 7, I don't know where the 10 came from
    */
    The code runs fine, but your math is off. Any number times zero, has a product of zero iirc, not 139.

    A million times zero is still just zero. (1,000,000 * 0 == 0)

    So re-check your equation, and I'll look back for it, after I eat some overdue dinner.

    If I've goofed up your program during the adjustment, let me know.

  11. #11
    Registered User
    Join Date
    Apr 2009
    Posts
    29
    Code:
    iTotal=0; /*clear iTotal*/
    iISBN[i]=cISBN[i]-48; /*turn ASCII numbers to base 10 for doing the arithmetic part next*/
    iTotal+=iISBN[i]*(i+1); /*times the element by 'it's position + 1', since ISBN weighting values are 1,2,3,4,5,6,7,8,9 and initial i is 0, and add it to iTotal*/
    
    iCheck=0; /*clear iCheck*/
    iCheck=iTotal%11; /*iCheck becomes the remainder of iTotal divided by 11, ISBN uses mod 11*/
    cout<<(iCheck); /*output iCheck, the remainder aka the ISBN check digit, and I used cout because printf gave me errors*/
    So, what is wrong in my calculations
    Last edited by Dakaa; 04-19-2009 at 10:22 PM.

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I don't know. When it says the "weighting values" are 123456789, does that mean the zero's in our ISBN example are wrong?

    All I can say is that the right values got into the char array, they were then translated into their numerical value, and went into the calculation loop.

    I will ponder the matter. Please check Google for an actual equation.

  13. #13
    Registered User
    Join Date
    Apr 2009
    Posts
    29
    Example, isbn is 013190190, you times the first isbn digit by 1, second digit by 2, third digit by 3, fourth digit by 5, fifth digit by 5, sixth digit by 6, seventh digit by 7, eighth digit by 8 and last digit by 9, because isbn's weight values are 1,2,3,4,5,6,7,8,9. Then you add 'em up which gives us 139, and isbn uses mod 11, so you divide the total by 11 and the remainder is the check digit.

    If the weight values are 9,1,4,6,3,7,5,2,8, you times the first digit by 9 and the second by 1 and third by 4 blah blah blah.

    Need to get this code working, before I start my other assignment which is similar to this, 'Australian Tax Number', understanding the concept is easy, but not writing it into c. (for me)

    EDIT: Sorry for the bad grammar, English is my 2nd language.
    Last edited by Dakaa; 04-20-2009 at 04:28 AM.

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    OK, let's see how that works in the program, now.

    Back in a bit.

    We weren't dividing and using the remainder, nor initializing iTotal in the right place:

    Code:
    
    //#include <iostream.h>
    #include <conio.h>
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
       char cISBN[10] = {"013190190"};
       int i,iLen,iNNF,iISBN[9],iTotal,iCheck;
        
    /* for(i=0;i<10;i++)
       {
          cISBN[i]='\0';
       }
                       
       printf("Enter ISBN ");
       gets(cISBN);
    */
       iLen=strlen(cISBN);
       if(iLen!=9)
       {
          printf("ISBN length error ");
       }
                                    
       else
       {
          iTotal = iNNF=0;
          for(i=0;i<iLen&&iNNF==0;i++)
          {
             if((cISBN[i] - '0'< 0)||(cISBN[i] - '0'> 9))
             {
                printf("ISBN numerical error ");
                iNNF=1;
             }
             else
             {
                //iTotal=0;
                iISBN[i]=cISBN[i]-48;
                iTotal += iISBN[i]*(i+1);
             }
          }
       }
       printf("\niTotal: %d  Check digit: %d\n", iTotal, (iTotal % 11));
       getch();
       return 0;
    }
    /*
    Error 1 (gone): if(cISBN[i]<0||>9) /*expected primary-expression before '>' token*/
    thanks Adak and MK27.
    
    Error 2:
    1*(0)+2*(1)+3*(3)+4*(1)+5*(9)+6*(0)+7*(1)+8*(9)+9* (0)=139
    139/11=12 rem 7
    139=7(mod11)
    Check digit is 7.
    
    my horrible code
    input 013190190
    output 7
    
    it gave me "ISBN numerical error 10" instead of 7, I don't know where the 10 came from
    */
    Last edited by Adak; 04-20-2009 at 12:57 AM.

  15. #15
    Registered User
    Join Date
    Apr 2009
    Posts
    29
    thanks...
    Last edited by Dakaa; 04-20-2009 at 03:53 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Check application visibility
    By 3saul in forum Linux Programming
    Replies: 2
    Last Post: 02-13-2006, 05:13 PM
  2. newbie programmer - needs help bad.
    By hortonheat in forum C Programming
    Replies: 17
    Last Post: 10-20-2004, 05:31 PM
  3. Roman number converter
    By BalanusBob in forum C++ Programming
    Replies: 8
    Last Post: 04-23-2002, 06:29 AM
  4. ISBN modulus 11 check
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 01-15-2002, 01:03 PM
  5. questions re modulus 10 aka check digit stuff
    By DaWench in forum C++ Programming
    Replies: 2
    Last Post: 11-26-2001, 11:14 PM