Thread: Problems reading formatted input with sscanf

  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    158

    Question Problems reading formatted input with sscanf

    I've searched a lot in google for examples on how to use sscanf but I didn't find many, in fact, I only found one page with some live examples, every other site found, only had the syntax explanation and nothing else...

    I want to be able to read a string with sscanf and return true if it matches exactly, otherwise return false. The string to be read must be exactly like this: integer, comma, integer, double quote, text, double quote, comma, single character.

    Real example:
    1,5,"some text",h

    The single character at the end, must only be an 'h' or a 'v'.

    So, can anyone help me out how to do that? I tried and tried from what I understand of sscanf but couldn't make it work, I guess I don't understand at all how sscanf works. If possible, it would be nice to save (in the above example) 1, 5, some text and h to variables cause I'll need them later of course and one more thing that I think it's more difficult, but if possible I also would like to include the character "double quote" and "comma" between the double quote text. Dunno if it's possible cause as I said before, I don't understand much of sscanf.

    If only there was perl compatible regular expressions included in the standard C...

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    It works just like scanf. Set up your arguments, and check the return value of sscanf to make sure it stores the expected number of items. If it isn't, then it wasn't a perfect match.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Mar 2006
    Posts
    158
    that's the whole problem, I can't do it... I've tried, I just can't seem to understand how to do what I want, that's why I'm here asking for help....

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    I got it. It works just like quzah said; you have to carefully set up your variables and the format string in order for it to work correctly. I used some strange identifiers to get this to work, so study the sscanf manpage, and the example below:
    Code:
    int num, num2;
    char matchme[]="1,5,\"some text\",h";
    char str[40];
    char ch[3];
      if (sscanf(matchme, "%d,%d,%[^,],%[hv]", &num, &num2, str, ch ) < 4)
          printf("Error reading string.\n");
      else
          printf("%d %d %s %s\n", num, num2, str, ch);
    
    /*  Output: 
    ** 1 5 "some text" h 
    */
    Last edited by whiteflags; 05-07-2006 at 08:27 PM. Reason: code and link fixing

  5. #5
    Registered User
    Join Date
    Mar 2006
    Posts
    158
    doesn't work exactly what I want... first, you forgot the double quotes, it also works with 1,5,some text,h and I don't want it, it also works with 1,5,"some text", hv, and I also don't want that...

  6. #6
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Try
    sscanf(matchme, "%d,%d,\"%s\",%1[hv]".............etc..........

  7. #7
    Registered User
    Join Date
    Mar 2006
    Posts
    158
    also doesn't work, the string part will get everything after the first ", like 'some text,h' and that %1[hv] also dosen't work quite right, as it will accept more than 1 character and it must specifically be just one...

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Use %c if you want just one character.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Fountain of knowledge.
    Join Date
    May 2006
    Posts
    794
    Quote Originally Posted by Nazgulled
    also doesn't work, the string part will get everything after the first ", like 'some text,h' and that %1[hv] also dosen't work quite right, as it will accept more than 1 character and it must specifically be just one...
    I think the %1[hv] bit should work cos I think the 1 specifies 1
    character. Maybe try 1.1 instead?
    Anyway I am prettty sure %1[hv] does work so check it.
    anyway it's not my homework so good luck

  10. #10
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by Nazgulled
    doesn't work exactly what I want... first, you forgot the double quotes, it also works with 1,5,some text,h and I don't want it, it also works with 1,5,"some text", hv, and I also don't want that...
    I'm sorry, I wasn't quite clear on your restrictions. This is the strictest format string you can give sscanf in order for it to work properly.
    Code:
      int num, num2;
      char matchme[]="31,3,\"Fun in the sun\",v", str[40], ch[3];
      if (sscanf(matchme, "%d,%d,\"%[^\"]\",%1[hv]", &num, &num2, str, ch ) < 4 )
          printf("Error reading string.\n");
      else {
          char foo = ch[0];
          printf("%d %d %s %c\n", num, num2, str, foo);
     }
    I am sorry, but the bracket identifier is more strict than %c or %s in both cases, since sscanf first reads two digits separated by a comma, a double quote and does nothing with it, then reads everything up to but excluding the next quote, then reads the quote and does nothing with it, then a comma, then a h or v. It fails if it doesn't match exactly. Pretty sweet!

    The bracket identifier also requires a char array that must be large enough to hold all the input it should read and a terminating NUL. Why is it a problem for you to just take ch[] and assign the first argument to a normal char? It's not that hard or evil.
    Last edited by whiteflags; 05-08-2006 at 11:35 PM.

  11. #11
    Registered User
    Join Date
    Mar 2006
    Posts
    158
    %1[hv], in my tests, this didn't work... cause you will still be able to input more than 1 char, what this will do is truncate that input with only 1 char... so, if you put something like 1,5"fdfdsfs",habcd it will remove the "abcd" and the "h" will still be there and working, and I dont' that...

    anyway, I'll just take a different approach and validate some things with sscanf and the others I'll just parse the string char by char...

  12. #12
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Ah crap!! I had a brain fart!
    Code:
    "%d,%d,\"[^\"]\",%1[hv]\n"
    If you add a token like newline to the end it will reject sequences like "hvuduf"

    I'm so sorry it took this long.
    Last edited by whiteflags; 05-09-2006 at 10:46 AM.

  13. #13
    Registered User
    Join Date
    Mar 2006
    Posts
    158
    thanks, I'll test it out...

  14. #14
    Registered User
    Join Date
    Mar 2006
    Posts
    158
    no, it didn't work, it accepted strings with more than 1 char in the end... anyway, I just took a different approach.

    I used scanf with "%d,%d,%s" then I just checked specific positions of the string to see if there was a double quote at the beggining a double quote in the 3 char counting from the end, a comma in the 2 char from the end and only one 'h' or 'v' in the end.

    I'm just having one problem with that, if I input something like: 1,5,"some text",h
    the %s will only capture "some when I want it to capture "some text",h, if the space was not there it would capture "sometext",h, which is what I want.

    So, how can I use sscanf to capture everything into a string, even the spaces?

  15. #15
    Registered User
    Join Date
    Mar 2006
    Posts
    158
    why didn't I thought of that... well, actually, in my real code, I have a function to read strings and the maximum is 256 chars, however, when reading chars to the string, I only allow 255 and if it ever reaches that, I'll add a \0 to the last position, otherwise, when the user finishes reading the string, I'll add \0, so, if I use that on sscanf, I think it will always reach the \0.

    But in your example, you put /0 instead of \0, is this a typo or it mus be like this?

    EDIT: that's odd, this reply was for a post that was just above this one
    Last edited by Nazgulled; 05-09-2006 at 02:45 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 02-02-2009, 07:27 AM
  2. Reading from an input file + processing
    By Mooncow in forum C Programming
    Replies: 2
    Last Post: 12-01-2008, 02:45 AM
  3. Formatted input
    By vaibhav in forum C++ Programming
    Replies: 1
    Last Post: 10-21-2005, 11:19 PM
  4. reading input files with different types of data
    By sanu in forum C++ Programming
    Replies: 4
    Last Post: 06-27-2002, 08:15 AM
  5. function and input problems
    By meka in forum C++ Programming
    Replies: 4
    Last Post: 09-22-2001, 11:56 AM