Thread: validate isbn

  1. #1
    Registered User
    Join Date
    Sep 2004
    Posts
    17

    Question validate isbn

    hey ,guys,i'm stuck trying to validate a ISBN number(w/o hyphens). I want it to check the last digit for a X and update the sum. But i keep getting the wrong sum. What's wrong in my code?

    [code]
    #include<stdio.h>
    #include<ctype.h>
    Code:
    int testISBN(char*);
    
    int main (void)
    {
    	int divisible;
    	char choice, trash;
    	char code[15];
    
    	do
    	{
    		printf("Enter an ISBN (book) number:\n");
    		fgets(code,15,stdin);
    
    		printf("The ISBN entered is:%s\n",code);
    		divisible = testISBN(code);
    		if (divisible == 1)
    					printf("\n\n\tValid ISBN Number\n");
    		else
    					printf("\n\n\tInvalid ISBN Number\n");
    			
    		printf("\nDo you wish to continue? (Y/N)\n");
    		choice = getchar();
    		trash = getchar();
    	}while(toupper(choice) != 'N');
    	
    	return 0;
    }
    
    int testISBN(char*code)
    {
    	int i;
    	int sum = 0;
    	int value;
    
    	for(i=9;i>=0; i--)
    	{
    		if((i==9) && (toupper(*(code + i)) == 'x'))
    			{
    				value = 10;
    			}
    		else
    			{
    				value = (int)(*(code + i)-48);
    			}
    		sum += value * (i+1);
    	}
    	printf("sum is %d",sum);
    	
    	if ((sum%11) == 0)
    		return 1;
    	return 0;
    }

  2. #2
    Registered User
    Join Date
    Mar 2005
    Posts
    11
    Code:
        if((i==9) && (toupper(*(code + i)) == 'x'))
    Perhaps you want:
    Code:
        if((i==9) && (toupper(*(code + i)) == 'X'))
    With an uppercase x.

  3. #3
    Registered User
    Join Date
    Sep 2004
    Posts
    17
    i try replacing with it with an uppeercase X(no good), what i would like to do is how this website explains corrrect ISBN by using mod 11

    http://www.ee.unb.ca/tervo/ee4253/isbn.html

    if iI input there number 0131391399, my sum does not equal to 143

  4. #4
    ex-DECcie
    Join Date
    Dec 2005
    Posts
    125
    I'm at work and only had about "half a cup of coffee's" time to look at your problem.

    I think the problem is when you are traversing the ISBN number.

    You're starting at the far end, and checking for 'X', and you traverse the number towards the beginning.

    The article you cite says that you multiply the last digit times 1, and the first digit times 10. You're actually doing the opposite.

    You're multipying the last digit times 10, working down to multipying the first digit times 1.

    I think that is your problem but again, I only had a couple of minutes to look at it.

  5. #5
    Registered User cbastard's Avatar
    Join Date
    Jul 2005
    Location
    India
    Posts
    167
    fgw_three is right.
    Code:
    char code[15];
    fgets(code,15,stdin);
    When you store like this.The most significant digit is stored at code[0].
    Code:
    for(i=9;i>=0; i--)
    	{
    		if((i==9) && (toupper(*(code + i)) == 'x'))
    			{
    				value = 10;
    			}
    		else
    			{
    	 value = (int)(*(code + i)-48); \\\By this Yor are moving from least signicant to most significant.
    			}
    		sum += value * (i+1);\\here you are multiplying with 10 with least significant,9 with.... so on.Your are doin opposite.
    	}
    Long time no C. I need to learn the language again.
    Help a man when he is in trouble and he will remember you when he is in trouble again.
    You learn in life when you lose.
    Complex problems have simple, easy to understand wrong answers.
    "A ship in the harbour is safe, but that's not what ships are built
    for"

  6. #6
    Registered User
    Join Date
    Sep 2004
    Posts
    17
    I've played with it and still not getting the right sum. Ok, how do i know when it's multiply by the numbers 1-10 in string array, then i'm confused after mulitpy out, then sum them. I know it's simply, I'm not thinking the right way to do this. Please help!!

    Code:
    #include<stdio.h>
    #include<ctype.h>
    
    int testISBN(char*);
    
    int main (void)
    {
    	int divisible;
    	char choice, trash;
    	char code[15];
    
    	do
    	{
    		printf("Enter an ISBN (book) number:\n");
    		fgets(code,15,stdin);
    
    		printf("The ISBN entered is:%s\n",code);
    		divisible = testISBN(code);
    		if (divisible == 1)
    					printf("\n\n\tValid ISBN Number\n");
    		else
    					printf("\n\n\tInvalid ISBN Number\n");
    			
    		printf("\nDo you wish to continue? (Y/N)\n");
    		choice = getchar();
    		trash = getchar();
    	}while(toupper(choice) != 'N');
    	
    	return 0;
    }
    
    int testISBN(char*code)
    {
    	int i;
    	int sum = 0;
    	
    
    	for(i=0;i<9; i++)  /*loop thru string;checking for char
    	{
    		if((i==9) && (toupper(*(code + i)) == 'X'))
    			{
    				how do i assign character X to 10
    				(i.e) *(code+9) =10;(maybe)
    				then update sum
    			}
    		else
    			{
    				sum = (int)(*(code + i)-48)*(i+1)/*if not char then mutilipy string with num(1-10) ,then sum*/
    			}
    		
    	}
    	printf("sum is %d",sum);/*making sure sum is correct before 
    					returning to main*/
    	
    	if ((sum%11) == 0)
    		return 1;
    	return 0;
    }

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Why don't you use more variables to make it clearer, as well as using array notation rather than pointer notation.
    Code:
    int testISBN(char*code)
    {
      int i;
      int sum = 0;
    
      for(i=0;i<9; i++)
      {
        int chVal;
        if( (i==9) && (toupper(code[i]) == 'X') )
        {
          chVal = 10;
        }
        else
        {
          chVal = code[i] - '0';
        }
        sum += chVal;
      }
      printf("sum is %d",sum);
    
      return ( sum % 11 ) == 0;
    }

  8. #8
    Registered User cbastard's Avatar
    Join Date
    Jul 2005
    Location
    India
    Posts
    167
    >>how do i assign character X to 10 (i.e) *(code+9) =10;(maybe) then update sum
    well,i dont know what exactly you mean by this.but if you wanna assign X(ascii) to the least significant digit.
    *(code+9)='X'

    Code:
    sum = (int)(*(code + i)-48)*(i+1)/*if not char then mutilipy string with num(1-10) ,then sum*/
    You want to multiply most significant with 10 n so on?
    so,it should be
    Code:
    sum = (int)(*(code + i)-48)*(10-i)
    //plus previous sum.
    Long time no C. I need to learn the language again.
    Help a man when he is in trouble and he will remember you when he is in trouble again.
    You learn in life when you lose.
    Complex problems have simple, easy to understand wrong answers.
    "A ship in the harbour is safe, but that's not what ships are built
    for"

  9. #9
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Code:
    int testISBN(char*code)
    {
    #define TEN 10
        int i;
        int sum = 0;
    
        for(i=0;i<=9; i++)  /*loop thru string;checking for char */
        {
            if (isdigit(*(code + i)))
                       sum  +=  ((*(code + i) -= '0') * (i+1));
                   else
                if((i==9) && (toupper(*(code + i)) == 'X'))
                {
                    //  how do i assign character X to 10
                    //  (i.e) *(code+9) =10;(maybe)
                    //  then update sum
                    sum += TEN * i; 
                }
        }
        printf("sum is %d",sum);/*making sure sum is correct before returning to main*/
    
        if ((sum%11) == 0)
            return 1;
        return 0;
    }

  10. #10
    Registered User
    Join Date
    Sep 2004
    Posts
    17
    i guess i'm not tell the truth for code, this is what i like to do
    take an isbn number with last digit is an X

    0 1 3 2 8 8 3 6 6 X,

    if i do have a char X ,then X =10

    then do this mulitiply each digit which I believe is a counting for loop

    0 1 3 2 8 8 3 6 6 10 char X replace with 10

    * 10 9 8 7 6 5 4 3 2 1
    _____________________________
    then sum
    0 +9 +24+14+48+40+12+18+12+10 = 187

    Any ideas?

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well you need to implement the right algorithm - it's not just a simple sum, nor everything multiplied by 10.
    Code:
    #include<stdio.h>
    #include<ctype.h>
    
    int testISBN(char*);
    
    int main (void)
    {
      int isValid;
      char code[15];
      char temp[100];
    
      do
      {
        printf("Enter an ISBN (book) number:\n");
        fgets(code,sizeof code,stdin);
    
        printf("The ISBN entered is:%s\n",code);
        isValid = testISBN(code);
        if (isValid) {
          printf("\n\n\tValid ISBN Number\n");
        } else {
          printf("\n\n\tInvalid ISBN Number\n");
        }
        printf("\nDo you wish to continue? (Y/N)\n");
        fgets( temp, sizeof temp, stdin );
      } while(toupper(temp[0]) != 'N');
    
      return 0;
    }
    
    /*
     * http://www.morovia.com/supportforum/forum_posts_TID_55_PN_1.html
     */
    int testISBN(char*code)
    {
      int i;
      int sum = 0;
      int check;
    
      /* sum first 9 digits, as per algorithm */
      for ( i = 0 ; i < 9 ; i++)
      {
        int chVal = code[i] - '0';  /* the numeric value of the char */
        int pos = i + 1;            /* the numeric value of its position */
        sum += chVal * pos;
      }
    
      /* 10th digit is the checksum */
      if ( toupper(code[9]) == 'X' ) {
        check = 10;
      } else {
        check = code[9] - '0';
      }
    
      printf( "Sum=%d, Sum%%11=%d, check=%d\n", sum, sum%11, check);
      /* sum % 11 should be the check */
      return ( sum % 11 ) == check;
    }
    
    
    // results
    $ ./a.out
    Enter an ISBN (book) number:
    0131103628
    The ISBN entered is:0131103628
    
    Sum=107, Sum%11=8, check=8
    
    
            Valid ISBN Number
    
    Do you wish to continue? (Y/N)
    n

  12. #12
    Registered User
    Join Date
    Sep 2004
    Posts
    17

    Wink

    hey, thanks to all for your help, I'm almost home to finish it. I had to change some of it to understand it myself. I'm still having probably changing the character X to the number 10. Code sums to the right value when the X in not entered. I can see that when character X is entered a 40 appears(everytime). I need a 10 there, to multiply thru times number 1.
    Code:
    #include<stdio.h>
    #include<ctype.h>
    
    int testISBN(char*);
    
    int main (void)
    {
        int choice,trash;
        int isValid;
        char code[15];
      
    
      do
      {
        printf("Enter an ISBN (book) number:\n");
        fgets(code,15,stdin);
    
        printf("The ISBN entered is:%s\n",code);
        isValid = testISBN(code);
        if (isValid) {
          printf("\n\n\tValid ISBN Number\n");
        } else {
          printf("\n\n\tInvalid ISBN Number\n");
        }
        printf("\nDo you wish to continue? (Y/N)\n");
        choice=getchar();
    	trash=getchar();
      } while(toupper(choice) != 'N');
    
      return 0;
    }
    
    
    int testISBN(char*code)
    {
      int i;
      int sum = 0;
    
    
      /* sum first 9 digits */
      for ( i = 9 ; i>=0 ; i--)
      {
        int chVal = (*(code+i)) - 48; /* the numeric value of the char */
        int pos = 10-i;               /* the numeric value of its position */
        printf("chval is %d\n,pos is +%d\n",chVal,pos);
                                      /* i put this here to check values of  
                                             strings and position number*/ 
    
      /* 10th digit is the checksum */
      if (toupper(code[9]) == 'X' ) 
      {
    	*(code+9)=10;
    	sum+=chVal*pos;
      }
      else
      {
        sum+=chVal*pos;
      }
      }
      printf("Sum=%d", sum);
      /* sum / 11 is check */
      return ( sum /11 );
    
    }

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    It's remakable how you can take something which works and trash it with dumb stuff like
    > return ( sum /11 );

    Where in the hell did you get division from when the algorithm clearly states modulus.

    > /* 10th digit is the checksum */
    This code was OUTSIDE the loop for a reason - why did you corrupt it and put it inside the loop?

    Ghod

  14. #14
    Registered User
    Join Date
    Sep 2004
    Posts
    17
    Salem, didn't mean any harm,i'm just playing around with it, so that i may understand it. here is your code you post. For example the last digit, if a char X was entered, then it mulitplies it with a 40. I would like it to be a 10. It does check for a toupper 'X', or replaces it with a check =10. Try this number:013288366X,
    my sum should be 187, 187%11 =0, then valid isbn.

    Code:
    #include<stdio.h>
    #include<ctype.h>
    
    int testISBN(char*);
    
    int main (void)
    {
      int isValid;
      char code[15];
      char temp[100];
    
      do
      {
        printf("Enter an ISBN (book) number:\n");
        fgets(code,sizeof code,stdin);
    
        printf("The ISBN entered is:%s\n",code);
        isValid = testISBN(code);
        if (isValid==0) {
          printf("\n\n\tValid ISBN Number\n");
        } else {
          printf("\n\n\tInvalid ISBN Number\n");
        }
        printf("\nDo you wish to continue? (Y/N)\n");
        fgets( temp, sizeof temp, stdin );
      } while(toupper(temp[0]) != 'N');
    
      return 0;
    }
    
    /*
     * http://www.morovia.com/supportforum/forum_posts_TID_55_PN_1.html
     */
    int testISBN(char*code)
    {
      int i;
      int sum = 0;
      int check;
    
      /* sum first 9 digits, as per algorithm */
      for ( i = 0 ; i<=9 ; i++)
      {
        int chVal = code[i] - '0';  /* the numeric value of the char */
        int pos = 10-i;            /* the numeric value of its position */
        sum += chVal * pos;
    printf("chval is %d\n,pos is +%d\n",chVal,pos);
      }
    
      /* 10th digit is the checksum */
      if ( toupper(code[9]) == 'X' ) {
        check = 10;
    	
      } else {
        check = code[9] - '0';
      }
    
      printf( "Sum=%d, Sum%%11=%d, check=%d\n", sum, sum%11, check);
      /* sum % 11 should be the check */
      return ( sum % 11 );
    }

  15. #15
    Registered User
    Join Date
    Mar 2005
    Posts
    140
    First, that's not Salem's code, some of your changes are still there.

    The page you linked to has two different algorithms. I believe you are trying to implement the second one.

    I don't understand why you find it more intuitive to count backwards with your for loop.

    All you have to do is loop through the array.
    Convert the element to an int.
    Determine the multiplier (10 minus current position).
    Keep a sum of digit * multiplier.
    The only trick is: X means 10 (apparently this should only occur in the last position)
    return sum % 11

    Code:
    int testISBN(char*code)
    {
      int i;
      int chVal,multiplier;
      int sum = 0;
    
      for ( i = 0 ; i <= 9 ; i++)
      {
        if ( toupper(code[i]) == 'X' ) {
            chVal = 10;
        } else {
            chVal = code[i] - '0';
        }
    
        multiplier = 10-i;
        sum += chVal * multiplier;
      }
    
      return ( sum % 11 );
    }
    You can add validation that each elements is a digit, and the last element is a digit or 'X'

    Hmm, just looked... this is actually very close to your original attempt, except for the couting backwards part.
    Last edited by spydoor; 02-27-2006 at 09:59 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. need help reading a file (isbn program)
    By bigmac(rexdale) in forum C Programming
    Replies: 2
    Last Post: 05-16-2008, 10:56 PM
  2. Processing a book ISBN
    By richdb in forum C Programming
    Replies: 13
    Last Post: 08-11-2006, 11:14 PM
  3. Validate a user input integer?
    By criticalerror in forum C++ Programming
    Replies: 20
    Last Post: 12-07-2003, 08:30 PM
  4. last part of program i hope to validate
    By sturm100 in forum C Programming
    Replies: 8
    Last Post: 07-10-2002, 06:51 AM
  5. validate alphabets and numbers
    By sturm100 in forum C Programming
    Replies: 4
    Last Post: 07-09-2002, 08:04 AM