#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    27
    Rep Power
    0

    Defining function and parameter based on a string


    The input should be like this:
    "Word n", where "n" is an integer,
    or
    "Word n n"
    or
    "Word"

    Then, based on the word used, I'll call a function and pass "n" or "n n" as parameters.

    So there will be scanf's followed by some "if's" where I'd compare the string and use the according function. Let's call them fun1, fun2,....

    How can I do this? My idea is something like:
    Code:
    scanf ("%s", string)
    or
    scanf("%s %d %d", string, &value1, &value2) // Won't work I guess.
    But I think the second won't work in the cases where there is 0 or 1 integers after the word.

    How can I do this? I can tell what function I'll use after the first 3 characters of the string, if that helps in a way.
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    Well it's a lot easier if you use fgets() to read a line, then sscanf to parse it.
    Code:
    char buff[BUFSIZ];
    char string[BUFSIZ];
    int value1, value2;
    int result;
    
    fgets( buff, BUFSIZ, stdin );
    result = sscanf(buff, "%s %d %d", string, &value1, &value2);
    switch ( result ) {
      case 1:  // 1 word, no numbers
        break;
      case 2:  // 1 word, 1 number
        break;
      case 3:  // 1 word, 2 numbers
        break;
      case 0:  // nothing at all
        break;
      case EOF:  // end of input
        break;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    27
    Rep Power
    0
    Originally Posted by salem
    Well it's a lot easier if you use fgets() to read a line, then sscanf to parse it.
    Code:
    char buff[BUFSIZ];
    char string[BUFSIZ];
    int value1, value2;
    int result;
    
    fgets( buff, BUFSIZ, stdin );
    result = sscanf(buff, "%s %d %d", string, &value1, &value2);
    switch ( result ) {
      case 1:  // 1 word, no numbers
        break;
      case 2:  // 1 word, 1 number
        break;
      case 3:  // 1 word, 2 numbers
        break;
      case 0:  // nothing at all
        break;
      case EOF:  // end of input
        break;
    }
    Just so I can understand, sscanf returns the number of "non-NULL" (or actually used) ... things in the buff?

    Isnt fgets suppose to be used for files? in this case, is stdin some kind of "temporary file"?
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    159
    Rep Power
    19
    Isnt fgets suppose to be used for files? in this case, is stdin some kind of "temporary file"?
    Yes fgets() is used with files, and stdin is a file that is opened when your program starts.

    Jim
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Originally Posted by VicFS
    Just so I can understand, sscanf returns the number of "non-NULL" (or actually used) ... things in the buff?

    Isnt fgets suppose to be used for files? in this case, is stdin some kind of "temporary file"?
    RTFM! (ie, read the manual!)

    If you're going to use a standard library function, then learn what it does! Read that function's documentation! Then you won't have to guess what it does, but rather you will know!

    Google on man page sscanf
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    27
    Rep Power
    0
    Code:
        scanf("%d ", &rep);
    
        for(i=0;i<rep;i++){ 
           fgets(buff, 32, stdin);  
           result = sscanf(buff, "%s %d %d",string , &value1, &value2); 
           switch(result){
                case 1:
                    print(l);
                break;
    
                case 2: 
                    if(string[2] == 'd') in_end(l,value1); /* With 1 word and 1 number, it could be either "first n" or "end n" */
                    else in_first (l,value);
                break;
    
                case 3:
                    switch_value(l,value1,value2);
                break;
                
    case EOF:
                break;
            }
    
        }
    This is where I'm at now. It works fine for small numbers, but when I do the repetition like 10 times, sometimes it will randomly crash around the sixth input, sometimes it'll get the tenth input and still wait for another one. I think I'm messing up with fgets and the values being printed by the function, but I have no clue how to fix it.
  12. #7
  13. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    How did you declare buff and string?

    32 is a very small buffer for a line of user input. That's why I suggested BUFSIZ
    thisIsALongWord 1234567 1234567
    would fill the buffer.

    > if(string[2] == 'd') in_end(l,value1); /* With 1 word and 1 number, it could be either "first n" or "end n" */
    > else in_first (l,value);
    I don't see a value - where is that declared?

    > scanf("%d ", &rep);
    You have to be careful mixing fgets() and scanf()
    The trailing space works, but it does make for some interesting user experiences sometimes.
    Consider using fgets() and sscanf() for ALL your input and conversion tasks.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    27
    Rep Power
    0
    Originally Posted by salem
    How did you declare buff and string?

    32 is a very small buffer for a line of user input. That's why I suggested BUFSIZ
    thisIsALongWord 1234567 1234567
    would fill the buffer.

    > if(string[2] == 'd') in_end(l,value1); /* With 1 word and 1 number, it could be either "first n" or "end n" */
    > else in_first (l,value);
    I don't see a value - where is that declared?

    > scanf("%d ", &rep);
    You have to be careful mixing fgets() and scanf()
    The trailing space works, but it does make for some interesting user experiences sometimes.
    Consider using fgets() and sscanf() for ALL your input and conversion tasks.
    string is a char[9], the longest word to be used on the entrance has 8 letters.
    buff is a char[32], but reading what you wrote I'll probably make it a larger, because it will prevent issues with big numbers.
    Value was supposed to be value1, I changed the names before posting so it was clearer and forgot the 1.

    As for scanf, I've played with the possible inputs and found out the problem wasn't in this part of the code but inside one of my functions. It's really weird because sometimes it works and sometimes it crashes at different points, with the same input.

    I mean, in the code above, if I just keep using the input: "first 1" 10 times and it crashes in the seventh input, then I run the program again and it works without crashing, then, I run again and it crashes when I'm freeing the list nodes at the very end.

IMN logo majestic logo threadwatch logo seochat tools logo