Thread: Is this the perfect input function?

  1. #1
    former member Brain Cell's Avatar
    Join Date
    Feb 2004
    Posts
    472

    Is this the perfect input function?

    Since 'scanf()' is really ugly dealing with inputs , i decided to write a function that will hopefully be perfect when asking for numbers from the user.

    The function is called 'getl()' (get long), it has 3 arguments and need no extra header files to be included. First and Second argument let you specify the range of max\min integer allowed to be input. Third takes a costumized message that will be displayed in these cases :
    1. When the user immdiatly hit <Enter> without entering anything.
    2. When the input doesn't belong to the range you specified.
    3. When the user enters an invalid input i.e : a mix of numbers and letters.
    4. When the user enters a real number (i.e: 4.5)


    The function will keep displaying your custom message and asking for another input untill you enter a valid one.

    here is the code :
    Code:
    #include <stdio.h>
    
    long getl(long, long , char *);
    
    int main(void)
    {
       long number;
    
       printf("Please enter a number :\n");
       number = getl(0,500,"Invalid Input.\n\nPlease enter a number :");
    
       printf("You've entered %d\n\n", number);
    
       system("PAUSE");
    
       return 0;
    }
    
    long getl(long min_int, long max_int, char *message)
    {
       char input[BUFSIZ];
       char *p;
       long result;
    
       for(;;)
       {
    
       if( fgets(input, sizeof(input), stdin) == NULL )
           printf("\nCould not read from stream\n");
    
       result = strtol(input, &p, 10);
    
          if(result <= max_int && result >= min_int && input[0]!='\n' && ( *p == '\0' || *p == '\n' ))
                 return result;
          else
              puts(message);
       }
    }
    Let me know what you guys think about it. And if it has any weak points , feel free to modify or add to it to make it even better.

    p.s : i know nothing is perfect , i use perfect as in "as good as possible".
    My Tutorials :
    - Bad programming practices in : C
    - C\C++ Tips
    (constrcutive criticism is very welcome)


    - Brain Cell

  2. #2
    Registered User Xzyx987X's Avatar
    Join Date
    Sep 2003
    Posts
    107
    A few things. First of all, your funtion doesn't return anything... Second, uf you manually handled the string to number conversion you could add an overflow check which would make it even better. BTW, correct me if I'm wrong but I don't think scanf was designed for keyboard input in the first place.

  3. #3
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    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.*

  4. #4
    former member Brain Cell's Avatar
    Join Date
    Feb 2004
    Posts
    472
    First of all, your funtion doesn't return anything...
    it does , 'return' doesn't neccessarly need to be placed at the end of the function.

    Second, uf you manually handled the string to number conversion you could add an overflow check which would make it even better.
    I don't clearly get what you mean here , but fgets() limits the input length and the function itself (getl()) wouldn't allow a number out of the range you specify anyway.

    BTW, correct me if I'm wrong but I don't think scanf was designed for keyboard input in the first place
    I'm not sure about what you say, but i doubt it.


    and thanks for the link Dave.

    Anyone else?
    My Tutorials :
    - Bad programming practices in : C
    - C\C++ Tips
    (constrcutive criticism is very welcome)


    - Brain Cell

  5. #5
    Registered User Xzyx987X's Avatar
    Join Date
    Sep 2003
    Posts
    107
    Errr, right. NM about the returning. Regarding the overflow check though, if you just limit the number of charectors you can input then you won't be able to get the full range of numbers unless your funtion uses hex or another compatible base for input, which you are not doing. Speaking of different bases, it would also allow you to set the base of the input which would be handy for inputting octal or hex numbers. And also, the reason why I say scanf probobly wasn't intended for kb input is because I can't possibly see how any programmer in their right mind would think a function that can crash you program depending on a user's input was a good idea.

  6. #6
    former member Brain Cell's Avatar
    Join Date
    Feb 2004
    Posts
    472
    Regarding the overflow check though, if you just limit the number of charectors you can input then you won't be able to get the full range of numbers
    the character limit equals BUFSIZ wich is 512 in my machine. 'long' is mostly 4 bytes wich gives a range from -2147483648 to 2147483647. Any input thats greater than 2147483647 or\and has more than 10 digits would be considred as an invalid input.

    how wouldn't i get the full range of numbers? and will you show me how would this overflow in an example?

    and regarding the octal and hex inputs , the function has been named 'get long' for a purpose .


    the reason why I say scanf probobly wasn't intended for kb input is because I can't possibly see how any programmer in their right mind would think a function that can crash you program depending on a user's input was a good idea.
    Thats not a reason to think it wasn't build for taking inputs from the keyboard. Think 'gets()'
    My Tutorials :
    - Bad programming practices in : C
    - C\C++ Tips
    (constrcutive criticism is very welcome)


    - Brain Cell

  7. #7
    Registered User
    Join Date
    Oct 2004
    Posts
    120
    and regarding the octal and hex inputs , the function has been named 'get long' for a purpose .
    Adding this functionality would make your method even more complete. Allowing the user to spcify their input preference (0x for hex, o for octal, etc) would allow an even greater range of uses. Just because its signed long doesn't mean it can't be represented in anything other than decimal.

  8. #8
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    I think it would also be more useful to allow inputs from other streams besides stdin. Maybe that should be a fgetl() function or something though
    If you understand what you're doing, you're not learning anything.

  9. #9
    Registered User Xzyx987X's Avatar
    Join Date
    Sep 2003
    Posts
    107
    Ok, I actually took a look at what strtol does and I guess your right, it's not a problem. I was assuming that 10 was the the max amount of chars you were allowing when actually it was the base. This pretty much solves the base handling too since all you'd have to do is make it a parameter in your function and pass it through. Actually strtol seems to be an extemely nice function. It handles pretty much every problem that could come up in number entry. And here I thought that all the stdio functions were crap.

  10. #10
    former member Brain Cell's Avatar
    Join Date
    Feb 2004
    Posts
    472
    Nice suggestions pablo615 and itsme86 , I think fgetl() would be cool. I'll work on it soon.

    How about the current getl()? do you think it has any flaws or bad practices?


    appreciate your replies..
    My Tutorials :
    - Bad programming practices in : C
    - C\C++ Tips
    (constrcutive criticism is very welcome)


    - Brain Cell

  11. #11
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    >How about the current getl()?

    I don't know any of the modifications you may have made, but I wonder why you process data that you didn't receive...
    Code:
       if( fgets(input, sizeof(input), stdin) == NULL )
           printf("\nCould not read from stream\n");
    
       result = strtol(input, &p, 10);
    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.*

  12. #12
    former member Brain Cell's Avatar
    Join Date
    Feb 2004
    Posts
    472
    DUH!! how did i miss that

    this will do :
    Code:
    if(fgets(input, sizeof(input), stdin)==NULL)
       {
           printf("\nCould not read from stream\n");
           return 0;
       }
    i guess its bug-free now

    Thanks Dave
    My Tutorials :
    - Bad programming practices in : C
    - C\C++ Tips
    (constrcutive criticism is very welcome)


    - Brain Cell

  13. #13
    Registered User
    Join Date
    Oct 2004
    Posts
    120
    Actually, that change is not bug free either, because 0 is a valid value that a user may enter. You can fix that a variety of ways.

    1.) Use exceptions to indicate a failure. I usually try to avoid exceptions because they slow things down sometimes.

    2.) Instead of returning a long, return an enum of possible return values, or a bool true false, and take the destination for the input in the argument list as a reference.

    Either method above will help make your function even more error proof.

    Also, I'd say forget the infinite for loop and allow the user to escape the entering of a value by pressing escape or typeing quit or something like that. That way the user isn't trapped.

  14. #14
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    Quote Originally Posted by pablo615
    ...exceptions...reference...
    You seem to be lost. Are you looking for the C++ board?
    hello, internet!

  15. #15
    Registered User
    Join Date
    Oct 2004
    Posts
    120
    DOH! I didn't even realize...my bad, too used to C++ hahaha

    Well, instead of pass by reference, pass a pointer to the long that will contain the input. And forget about the exception thing...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  4. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM