check digit

This is a discussion on check digit within the C Programming forums, part of the General Programming Boards category; @Jailan: Have you tried searching the forum? http://cboard.cprogramming.com/search.php Use "ISBN" as a key word. Sure several threads are about books. ...

  1. #16
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    @Jailan: Have you tried searching the forum?

    http://cboard.cprogramming.com/search.php

    Use "ISBN" as a key word. Sure several threads are about books. Several others offer previously asked version of your same question, and likely a solution lies therein as well.

    Thread titles like "Processing a book ISBN" or "validate isbn" spring to mind.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  2. #17
    Registered User
    Join Date
    Sep 2007
    Posts
    30
    Thanks for your help I managed to nut it out after a while but I need some more help;

    I need to split it up into seperate functions but each time I try I get a whole bunch of errors no matter what way I try to split it.

    Code:
    #include<stdio.h>
    
    int main()
    {
       char input[20] = { '\0' };
       char flag = 0;  
       int weight = 10; 
       int index = 0;  
       int sum=0;   
       int temp=0; 
       int noOfChars = 0;
       
    
     
       while(input[0] != '\n')
       {
          fgets(input, 20, stdin);
     
          while(index < 20)
          {
             if((input[index] >= 0x30 && input[index] <= 0x39) || 
                (input[index] == 'X' || input[index] == 'x'))
             {
                if(input[index] == 'X' || input[index] == 'x')
                {
                   temp = 10;
                }
                else
                {
                   temp = input[index] - '0';
                }
                temp = temp * weight;
                sum += temp;
                weight--;
                noOfChars++;
             }
             else if(input[index] == '\n')
             {
                flag = 1;
                index++;
    
                while(index < 20)
                {
                   input[index] = '\0';
                   index++;
                }
                break;   
             }
             index++;
          }
    
          if(flag != 1 || noOfChars != 10)
          {
             if(input[0] != '\n')
             {
                printf("Invalid ISBN number\n\n");
             }
          }
          else
          {
             temp = sum % 11;
                
             if(temp == 0)
             {
                printf("Valid ISBN number\n\n");
    
             }
             else
             {
                printf("Invalid ISBN number\n\n");
             }
          }
          weight = 10;
          noOfChars = 0;
          index = 0;
          sum = 0;
          flag = 0;
    
       }
    
       return 0;
    }

  3. #18
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
                while(index < 20)
                {
                   input[index] = '\0';
                   index++;
                }
    Why? Setting input[index] = '\0' may be fine, but there's no need to fill the entire rest of the string.

    Code:
          weight = 10;
          noOfChars = 0;
          index = 0;
          sum = 0;
          flag = 0;
    Stick these at the start of the code.

    Code:
             if((input[index] >= 0x30 && input[index] <= 0x39) || 
                (input[index] == 'X' || input[index] == 'x'))
    is easier to read (and write) as:
    Code:
             if(isdigit(input[index]) || tolower(input[index]) == 'x')
    Similarly, use:
    Code:
                if(tolower(input[index]) == 'x')
    I don't really see the point of your "flag" variable. Surely if there's no newline because the input is too long to fit in 20 chars, it will fail due to "not the right number of digits".

    Code:
    temp = temp * weight;
    // why not
    temp *= weight
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #19
    Registered User
    Join Date
    Sep 2007
    Posts
    30
    These are the errors I am getting back:
    ==> Your program only contains the main function
    Your program must be split into appropriate functions

    ==> At least one function in your code must use 'call by
    You do not appear to have done this in your program.

    Code:
          weight = 10;
          noOfChars = 0;
          index = 0;
          sum = 0;
          flag = 0;
    Stick these at the start of the code.
    I did this but I get

    ==> Global variables are not allowed in this subject.
    Last edited by Jailan; 09-19-2007 at 06:18 PM.

  5. #20
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Ehm, when I said start of the code, I meant the start of the for-loop. That is your current code (as posted earlier) sets these variables at the end of the loop, rather than at the start of the loop. It makes the code easier to read if you set the variables at the start of the loop.

    You obviously have some requirement to use a function, and you should break out the function to check the number. I would write it something like this :

    Code:
    int main() 
    {
         char str[20];
       
         do {
            printf("Enter a ISBN or empty line to exit:");
            fgets(str, sizeof(str), stdin);
            if (str[0] != '\n')  checkISBN(str);
        } while (str[0] != '\n');
        return 0;
    }
    I'll leave it to you to implement the "checkISBN" code - but essentially it is most of the code you've got in main that needs to move to the checkISBN function.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #21
    Registered User
    Join Date
    Sep 2007
    Posts
    30
    Removed
    Last edited by Jailan; 09-20-2007 at 10:58 PM.

  7. #22
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Whilst having inputFlush as a function is certainly a good idea, and checking digit in a function isn't bad either, I think the "correct" thing to do is to split the check of the ISBN part into a separate function that takes a string as input.

    I personally have nothing against having main last - but that's probably heavily influenced by my previous Pascal experience, where code is built "bottom up", meaning that the most basic functions are declared first, the the functions calling the basic function etc. But there's no strict rule that you have to do it one way or the other in C.

    The cause of errors in your second piece of code, however, are caused by the fact that a function has to be declared (as a prototype at least) before it is called.

    There are some style points I'd like to point out too:
    Your input flush is overcomplicated: Use something like this:

    Code:
    char ch;
    while((ch = getchar()) != '\n' && ch != EOF) ;

    Don't pass a flag to inputFlush, check the flag in the code before calling inputflush.

    Code:
          if(flag != 1 || noOfChars != 10)
    I'm sure that flag will only be zero if noOfChars is NOT ten, so checking both doesn't really lead to anything useful. [Because the only way that the string doesn't end on a '\n' is if there's more than 19 chars in the input, which is higher than 10].


    I would also add that the only position in an ISBN that is allowed to be X is the last one, so it would be possible to enter an invalid ISBN and get an "OK" answer.

    You also don't bail out if there's invalid input, e.g.
    A12345B 6789AX would be accepted as 123456789X, ignoring the A's.

    And you still don't use "tolower" to check if the 'X' is an x.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #23
    Registered User
    Join Date
    Sep 2007
    Posts
    30
    Ignoring the over complicated stuff cause I just want it to work at the moment then I'll play around with it looking better... I tried declaring the two functions at the start but just got the below errors

    "isb2.c", line 73: warning: identifier redeclared: inputFlush
    current : function(char) returning void
    previous: function() returning void : "isb2.c", line 3
    "isb2.c", line 87: warning: identifier redeclared: decodeDigit
    current : function(char, pointer to int) returning int
    previous: function() returning int : "isb2.c", line 4
    isb2.c:73: error: conflicting types for 'inputFlush'
    isb2.c:73: note: an argument type that has a default promotion can't match an em
    pty parameter name list declaration
    isb2.c:3: error: previous declaration of 'inputFlush' was here
    isb2.c:73: error: conflicting types for 'inputFlush'
    isb2.c:73: note: an argument type that has a default promotion can't match an em
    pty parameter name list declaration
    isb2.c:3: error: previous declaration of 'inputFlush' was here
    isb2.c:87: error: conflicting types for 'decodeDigit'
    isb2.c:87: note: an argument type that has a default promotion can't match an em
    pty parameter name list declaration
    isb2.c:4: error: previous declaration of 'decodeDigit' was here
    isb2.c:87: error: conflicting types for 'decodeDigit'
    isb2.c:87: note: an argument type that has a default promotion can't match an em
    pty parameter name list declaration
    isb2.c:4: error: previous declaration of 'decodeDigit' was here

    Code:
    #include<stdio.h>
    
    int decodeDigit(char ch, int *temp);
    void inputFlush(char flag);
    
    int main()
    { etc etc

  9. #24
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Did you make any other changes?

    The error text you're showing doesn't quite match the code - you didn't by any chance do some of it and then forgot to save the final changes?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #25
    Registered User
    Join Date
    Sep 2007
    Posts
    30
    Removed
    Last edited by Jailan; 09-20-2007 at 10:58 PM.

  11. #26
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    That isn't a good function prototype. You should have the arguments as well.

    Like this:
    Code:
    int decodeDigit(char ch, int *temp);
    void inputFlush(char flag);
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #27
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I just realized that you have removed the arguments from your function calls in the code - you shouldn'tt do that.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #28
    Registered User
    Join Date
    Sep 2007
    Posts
    30
    ahhhh ok cheers!

    Now I'm getting

    "isb2.c", line 22: prototype mismatch: 0 args passed, 2 expected
    "isb2.c", line 46: prototype mismatch: 0 args passed, 1 expected

    I can't win!

  14. #29
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Jailan View Post
    ahhhh ok cheers!

    Now I'm getting

    "isb2.c", line 22: prototype mismatch: 0 args passed, 2 expected
    "isb2.c", line 46: prototype mismatch: 0 args passed, 1 expected

    I can't win!
    You were writing as I was posting as well. I would have got there quicker if I hadn't had to remove your "doublespacing" - are you using WORD or something like that for your editing?

    --
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #30
    Registered User
    Join Date
    Sep 2007
    Posts
    30
    Oh ok I'll go put it back... Thanks.

Page 2 of 3 FirstFirst 123 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. BN_CLICKED, change button style
    By bennyandthejets in forum Windows Programming
    Replies: 13
    Last Post: 07-05-2010, 11:42 PM
  2. Need help with a program, theres something in it for you
    By engstudent363 in forum C Programming
    Replies: 1
    Last Post: 02-29-2008, 12:41 PM
  3. Adding a Large number digit by digit
    By mejv3 in forum C Programming
    Replies: 23
    Last Post: 09-21-2007, 03:00 PM
  4. Adding a Large number digit by digit
    By mejv3 in forum C Programming
    Replies: 1
    Last Post: 09-14-2007, 03:28 AM
  5. Check application visibility
    By 3saul in forum Linux Programming
    Replies: 2
    Last Post: 02-13-2006, 04:13 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21