Thread: Need a list of acceptable characters

  1. #1
    Registered User
    Join Date
    Sep 2017
    Posts
    93

    Need a list of acceptable characters

    I'm building a terminal calculator and I'm thinking I need a list of acceptable characters.

    Basically the only acceptable characters are 0 - 9 and '\n'. If any other character is found, I need to throw an error and ask the user to retry.

    I'm thinking of using strchr to do this. Look for anything !0, !1, !2, and so on.

    Then I need to take my CharacterBuffer[80] and place it into a double variable (InputNumber0 and InputNumber1).

    Here's the WIP:
    Need a list of acceptable characters-screen-shot-2017-10-18-9-06-39-pm-jpg

  2. #2
    Banned
    Join Date
    Aug 2017
    Posts
    861
    soo sorry if I am interrupting your line of thought, but if you are using this in conjunction with your other function that is already finding 1 - 4, why are you doing it again? just make it go from 1 - 9. this function is already passing in a uint8_t ASDM, which is a type int into itself, so you should be able to use your input from your pram with isdigit. but your data type even thought it is of type int it is uint8_t so that put it in a question mark status.


    ( in my option though isdigit is pretty much useless, but it maybe applicable if you're going to pass in a
    number 1 - 9 ; 0 ) ASCII vs UNICODE too needs to be taken into consideration.

    Code:
    int FunctionASDM( uint8_t ASDM)
    {
    // The isdigit() function shall return non-zero if c 
    // is a decimal digit; otherwise, it shall return 0.
    // if is a digit 1 - 9; 0 of type int
       if ( isdigit(ASDM) == 0 )
    {
    return -1;   ( an error  code )
    
    }
    else
    {
      do your work on ASDM
    }
    
    return 0;
    
     }
    this is not my logic mind you. in your line of thought in what it looks like how you are trying to accomplish what you're trying to accomplish . isdigit

    just questing your logic is all , pls take no offense.

    I am a little disappointed you may not have look at what I left you with in your other post on this subject.

    How is my code?
    Last edited by userxbw; 10-18-2017 at 08:57 PM.

  3. #3
    Banned
    Join Date
    Aug 2017
    Posts
    861
    you can use this one just tear it apart and restructure to use what is applicable
    strrchr searches for what you are looking for , if found then work with it. C library function - strrchr()

    Code:
    
    // 1 = add 2 = subtract 3 = mlutiply 4 = divide 
    int findOperator(int *operation, int *num1, int *num2, char *c)
    {
        const char add = '+';
        const char subtract = '-';
        const char multiply = 'x';
        const char divide = '/';
        char *tok1, *tok2, *saveptr;
        char str1[1+strlen(c)];
        strcpy(str1, c);
      
           if (strrchr(c, add) )
        {
        tok1 = strtok_r(c, "+", &saveptr);
        tok2 = strtok_r(NULL, "+", &saveptr);
    
            if ( tok2 == NULL)
            {
                return -1;
            }
         else
            {
                tok1 = strtok_r(str1, "+", &saveptr);
                tok2 = strtok_r(NULL, "+", &saveptr);
                *num1 = atoll(tok1);
                *num2 = atoll(tok2);
                *operation = 1;
                   return 1;
             }
        
        }
           if (strrchr(c, subtract) )
        {
        tok1 = strtok_r(c, "-", &saveptr);
        tok2 = strtok_r(NULL, "-", &saveptr);
    
            if ( tok2 == NULL)
            {
                return -1;
            }
         else
            {
                tok1 = strtok_r(str1, "-", &saveptr);
                tok2 = strtok_r(NULL, "-", &saveptr);
                *num1 = atoll(tok1);
                *num2 = atoll(tok2);
                *operation = 2; 
    
               return 1;
             }
        
        }
           if (strrchr(c, multiply) )
        {
        tok1 = strtok_r(c, "x", &saveptr);
        tok2 = strtok_r(NULL, "x", &saveptr);
    
            if ( tok2 == NULL)
            {
                return -1;
            }
         else
            {
                tok1 = strtok_r(str1, "x", &saveptr);
                tok2 = strtok_r(NULL, "x", &saveptr);
                *num1 = atoll(tok1);
                *num2 = atoll(tok2);
                *operation = 3;
                 return 1;
             }
        
        }
           if (strrchr(c, divide) )
        {
        tok1 = strtok_r(c, "/", &saveptr);
        tok2 = strtok_r(NULL, "/", &saveptr);
    
            if ( tok2 == NULL)
            {
                return -1;
            }
         else
            {
                tok1 = strtok_r(str1, "/", &saveptr);
                tok2 = strtok_r(NULL, "/", &saveptr);
                *num1 = atoll(tok1);
                *num2 = atoll(tok2);
                *operation = 4;
               return 1;
             }
        
        }
        
        return -1;
    }
    my first thought for what you are doing is putting the numbers in an char array then using that and looping around it with your input to check it until you find a match to a one number format if not then return your error code.
    Last edited by userxbw; 10-18-2017 at 09:20 PM.

  4. #4
    Registered User
    Join Date
    Sep 2017
    Posts
    93
    No, this is a different section of code.

    The previous was asking the user if he/she wants to add, subtract, divide or multiply.

    This is now getting numbers from the user to then perform the selected mathematical computation.

    I want to reject all characters except 0 - 1 and '\n' and store it in a buffer 80 bytes long.

    This is the function "FunctionASDM(ASDM)" that will be call to from the previous file, the one in my previous post.

  5. #5
    Registered User
    Join Date
    May 2015
    Posts
    90
    Quote Originally Posted by ImageJPEG View Post
    No, this is a different section of code.

    The previous was asking the user if he/she wants to add, subtract, divide or multiply.

    This is now getting numbers from the user to then perform the selected mathematical computation.

    I want to reject all characters except 0 - 1 and '\n' and store it in a buffer 80 bytes long.

    This is the function "FunctionASDM(ASDM)" that will be call to from the previous file, the one in my previous post.
    I think you meant 0 - 9.
    Why haven't you considered isdigit() as pointed out by userxbw?

  6. #6
    Banned
    Join Date
    Aug 2017
    Posts
    861
    or here in my first thought no how to do this, it is not complete .. hehe something to work with though if you want to do everything in that function. or get the numbers then work with it. finds 0 - 9 , can be changed.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int getNumber (void);
    int main (void)
    {
        
      if (   getNumber()  == -1)
      printf(" hey that is not right\n");
        
    return 0;
    }
    
    
    
    
    int getNumber (void)
    {
        char *buffer = NULL;
        char *ret;
        int what = 0;
        int count = 0, count1;
        size_t len = 0;
        int flag = 0;
       const char whatNumbers[10] =  { '1', '2', '3', '4',
          '5', '6', '7', '8',
          '9', '0'};
          
        const  char *ptr = whatNumbers; 
      
      printf("enter a number 1 - 9\n");
      while ( flag != 1 )
         {
             getline(&buffer, &len, stdin);
                printf("len %d\n", len);
                
                what = strlen(buffer);
                printf("what %d\n", what);
                if ( what > 2)
                {
                    return -1;
                }else
                
                 
                
            for ( count = 0; count < sizeof(whatNumbers)/sizeof(whatNumbers[0]); count++)
            {  
                printf("%c \n", ptr[count] ) ;
                if (strrchr(buffer , ptr[count]) )
                {
                    printf("got it\n");
                    flag = 1;
                    break;
                }
            } 
                 
             
         } //end while
        
        return 0;
    }
    the loops are pretty much a hack job so do not pick on me. it is only a half of a completed thought.

    yes you are going to have to mod it a bit to make it fit your needs.

    output
    Code:
    userx@slackwhere:~/bin
    $ ./a.out
    enter a number 1 - 9
    3
    len 120
    what 2
    1 
    2 
    3 
    got it
    userx@slackwhere:~/bin
    $ ./a.out
    enter a number 1 - 9
    23
    len 120
    what 3
     hey that is not right
    userx@slackwhere:~/bin
    $
    Last edited by userxbw; 10-18-2017 at 10:52 PM.

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by userxbw
    ( in my option though isdigit is pretty much useless, but it maybe applicable if you're going to pass in a
    number 1 - 9 ; 0 ) ASCII vs UNICODE too needs to be taken into consideration.
    ASCII is Unicode compatible, meaning that the first 127 Unicode code points are just ASCII characters.

    As for validation, custom validation is alright, isdigit(x) in a loop would work before you convert with something like sscanf().

    But really sscanf() works great here. In particular I might write:
    Code:
    if (sscanf(CharacterBuffer, "%lf%c", &InputNumber0, &ClearString) == 2 && ClearString == '\n')
    {
       printf("The input was good. Your number = %f\n", InputNumber0);
    }
    Most functions that convert text to numbers already validate the string and return sensible errors otherwise. The only one that doesn't return a sensible error which you might be tempted to use here is atolf(), and that isn't standard.

    The problem with atolf() returns 0 if it fails, and there is no way to tell where, how, or even if it failed. (Zero is pretty unhelpful, when you consider that when you call atolf("0.0"); it is merely the correct result.)

  8. #8
    Banned
    Join Date
    Aug 2017
    Posts
    861
    someone took ASCII vs UNICODE into consideration just to see if they need to worry about it. Plus isdigit takes an int and returns an int.

    the easiest path would be to match a pattern, look of something that looks exactly like what it is you are looking for in this case. because char is an int ascii , it hold a number to tell the user what it is. this is why isdigit is useless, it has to be cast to an int first then passed to isdigit, then isidigt looks at its ascii code yep it is an int,

    therefore, by logic one would have to know the ascii code to then match the number value of that char to the ascii code to determine if it is a number 0 - 9 or a letter.

    so scanf and the way I posted putting that match one is looking for then put that into a loop using that array with a function that uses pattern searching to match the input to the pattern wanted to find.

    scanf

    C library function - scanf()

    or
    strrchr

    C library function - strrchr()

    would work because it does just that, looks for the like 'object' / pattern / char / one is seeking. eliminating the need to then check to see if it is a number or a letter, because 'a' does not look like a '1'

    then just check for size or lenght of string / char strlen returns length + \n so if length is over 2 then it is more than one number or char being passed into the stdin.


    I'd first check size, it if is over 2 then do not even bother looking at it, discard , ask again,
    then if it is 2 look at it, if match good, if not, reject it, ask again. your scanf or strrchr function will help you determine that decision.

    a more proficient way to write this is to just write your functions to tell you what you have, put your loop or loops in main to ask for input, and get input then pass the input to your functions then let them do the bulk of the work. ( I think I am repeating myself.)

    the point is you're writing a portion of your code again to use it again for something else, when it is already been figured out how to use it, and written to do so to get input, now just use that for getting your input off stdin then send that to your functions and let them do what you want with that ( data ) input instead of rewriting it in every function for everything you want to do. that takes more time, and energy, for you and space for your computer. think about it. more code the larger the program. the more it has to decompress and to read it all. Takes more time and energy to do that.

    logic board.

    1. ask for input
    2. get input
    3. check input
    4. if not wanted.
    5. discard input
    6. ask again
    7. go back to 2 start again.
    8. if wanted go to next step
    9. process input
    10. give results.

    if you are writing your own functions. use a logic board for them too. then add your functions to your original logic broad. just keep expanding on that while making your code as simple as possible. get some paper and write out your logic first if needed. then use that to check it to be sure you're not getting lost when you get into unknown territory and get caught up in trying to figure that part out. which may lead you astray on your well thought out original idea on how to write your program, but too stay open for changing it to make it more (catch phrase here) robust.
    Last edited by userxbw; 10-19-2017 at 07:42 AM.

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by userxbw View Post
    someone took ASCII vs UNICODE into consideration just to see if they need to worry about it. Plus isdigit takes an int and returns an int.
    Either way, the OP hasn't posted anything that uses Unicode yet, so it is a bit unnecessary to bring it up. The C language in particular has poor support for Unicode. If he was trying to program something that can use Unicode, we would notice it right away. It looks very different from code taught to students.

    the easiest path would be to match a pattern, look of something that looks exactly like what it is you are looking for in this case. because char is an int ascii , it hold a number to tell the user what it is. this is why isdigit is useless, it has to be cast to an int first then passed to isdigit, then isidigt looks at its ascii code yep it is an int,
    isdigit() may take an int, but that is only because isdigit(EOF); must be a valid call. In any case, anything smaller than an int, like a char, would be promoted to an int. You do not need to cast anything. It would work on any byte you could pass in.

    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    int main(void)
    {
       char ch;
       /* This loop will check every standard ASCII character and point out if it is a digit or not. */
       for (ch = 0; ch < 0x7F; ch++) {
          if (isdigit(ch)) {
             printf("%c <- digit\n", ch);
          }
          else if (isprint(ch)) { 
             printf("%c\t", ch);
          }
          else { 
             /* We don't want to accidentally print characters that aren't printable. */
             printf("%#2x\t", ch);
          }
          
          /* Make the result pretty by adding in a newline now and then. */
          if ((ch + 1) % 8 == 0) {
             putchar('\n');
          }
       }
       
       return 0;
    }
    
    C:\Users\jk\Desktop>sandbox
     0      0x1     0x2     0x3     0x4     0x5     0x6     0x7
    0x8     0x9     0xa     0xb     0xc     0xd     0xe     0xf
    0x10    0x11    0x12    0x13    0x14    0x15    0x16    0x17
    0x18    0x19    0x1a    0x1b    0x1c    0x1d    0x1e    0x1f
            !       "       #       $       %       &       '
    (       )       *       +       ,       -       .       /
    0 <- digit
    1 <- digit
    2 <- digit
    3 <- digit
    4 <- digit
    5 <- digit
    6 <- digit
    7 <- digit
    
    8 <- digit
    9 <- digit
    :       ;       <       =       >       ?
    @       A       B       C       D       E       F       G
    H       I       J       K       L       M       N       O
    P       Q       R       S       T       U       V       W
    X       Y       Z       [       \       ]       ^       _
    `       a       b       c       d       e       f       g
    h       i       j       k       l       m       n       o
    p       q       r       s       t       u       v       w
    x       y       z       {       |       }       ~
    I'd first check size, it if is over 2 then do not even bother looking at it, discard , ask again,
    then if it is 2 look at it, if match good, if not, reject it, ask again. your scanf or strrchr function will help you determine that decision.
    Either way, proficient use of the scanf() family of functions can do all of this if it is really necessary. Making your own validation code is instructive, but there is no reason to not use isdigit() if you should.

  10. #10
    Banned
    Join Date
    Aug 2017
    Posts
    861
    any hew the way I did it makes it less code, less complected, I am not going into neanderthal mode and break apart every stone trying to find the diamond. when all I need to break is kimberlite to get what I am looking for, or rewriting the same code twice. that is over kill, and perhaps bringing up ascii and unicode was over kill too, but it does not hurt to bring it up.

    mine is done
    Code:
    $ ./getline_test
    input a equation + * - / 
    100x43
    4300
    userx@slackwhere:~/bin
    $ ./getline_test
    input a equation + * - / 
    100/3
    20
    userx@slackwhere:~/bin
    $ ./getline_test
    input a equation + * - / 
    100+123456
    123556
    userx@slackwhere:~/bin
    $ ./getline_test
    input a equation + * - / 
    1002023-5
    1002018
    if I was to be only looking for one numbers I'd still just match them and eliminate the need for isdigit.
    Last edited by userxbw; 10-19-2017 at 04:52 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File output is not displaying an acceptable answer
    By ntomaski in forum C Programming
    Replies: 5
    Last Post: 03-20-2017, 06:25 PM
  2. Bad practice or acceptable?
    By Noose in forum C++ Programming
    Replies: 6
    Last Post: 06-09-2004, 01:43 AM
  3. is dev-c an acceptable alternative to djgpp?
    By Waldo2k2 in forum Tech Board
    Replies: 1
    Last Post: 03-20-2003, 01:58 PM
  4. Acceptable way to do this?
    By Sindolist in forum Windows Programming
    Replies: 2
    Last Post: 03-07-2002, 11:00 PM

Tags for this Thread