Thread: Using sscanf to extract integers frmo "[1,2,3,4]

  1. #1
    Registered User
    Join Date
    Oct 2011
    Location
    Montreal Canada
    Posts
    6

    Question Using sscanf to extract integers frmo "[1,2,3,4]

    All the examples of sscanf that I encountered use the %s, %d etc.
    the sscanf("[10,20,30,40]","%s, ... " does not work.
    I created the following test program

    Code:
    #include <stdio.h>
    
    int main(int argc,char *argv[])
    {
    int rc;
    char field1[1023];
    char field2[1023];
    char field3[1023];
    char field4[1023];
    char field5[1024];
    char field6[1024];
    char field7[1024];
    char field8[1024];
    
    if(argc<2)
    {
      printf("%s sscanf workare format \n",argv[0]);
      printf("Scan up to 8 fields and show results. \n\n");
      return 0;
    }
    *field1=0;
    *field2=0;
    *field3=0;
    *field4=0;
    *field5=0;
    *field6=0;
    *field7=0;
    *field8=0;
    
    
    printf("rc=sscanf(\"%s,%s\");\n",argv[1],argv[2]);
    printf("argv[1]=[\"%s\"]  argv[2]=[\"%s\"]\n",argv[1],argv[2]);
    printf("Scan up to 8 fields and show results. \n\n");
    
    
    rc=sscanf(argv[1],argv[2],&field1,&field2,&field3,&field4,&field5,&field6,&field7,&field8);
    
    printf("field1=\"%s\"\n",field1);
    printf("field2=\"%s\"\n",field2);
    printf("field3=\"%s\"\n",field3);
    printf("field4=\"%s\"\n",field4);
    printf("field5=\"%s\"\n",field5);
    printf("field6=\"%s\"\n",field6);
    printf("field7=\"%s\"\n",field7);
    printf("field8=\"%s\"\n",field8);
    printf("Scan rc=%d\n",rc);
    return 0;
    }

    I then tried
    scanfTest [12,23,1,3] "[%[^','],%[^','],%[^','],%[^[']']] "
    It returns

    Code:
    argv[1]=["[12,23,1,3]"]  argv[2]=["[%[^','],%[^','],%[^','],%[^[']']] "]
    Scan up to 8 fields and show results. 
    field1="12"
    field2="23"
    field3="1"
    field4="3]"
    field5=""
    field6=""
    field7=""
    field8=""
    Scan rc=4
    This small utility allowed me to test sscanf with various string arguments.
    How do I easily (using sscanf() eliminate the closing ] glued to field 4 ?

  2. #2
    Registered User
    Join Date
    Oct 2011
    Location
    Montreal Canada
    Posts
    6
    I discovered how to eliminate the trailing ] with the following example.

    scanfTest [12,23,1,3] "%[^','],%[^','],%[^','],%[^]]"
    rc=sscanf("[12,23,1,3],%[^','],%[^','],%[^','],%[^]]");
    argv[1]=["[12,23,1,3]"] argv[2]=["%[^','],%[^','],%[^','],%[^]]"]
    Scan up to 8 fields and show results.

    field1="[12"
    field2="23"
    field3="1"
    field4="3"
    field5=""
    field6=""
    field7=""
    field8=""
    Scan rc=4

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You don't need all those single quotes, and you do need to specify the field width to avoid buffer overflow, e.g., "[%1022[^,],%1022[^,],%1022[^,],%1022[^]]". If you need to parse with a variable number of these fields, then it would probably be better to use strtok in a loop.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Oct 2011
    Location
    Montreal Canada
    Posts
    6

    Single quotes.

    Quote Originally Posted by laserlight View Post
    You don't need all those single quotes, and you do need to specify the field width to avoid buffer overflow, e.g., "[%1022[^,],%1022[^,],%1022[^,],%1022[^]]". If you need to parse with a variable number of these fields, then it would probably be better to use strtok in a loop.
    Yes, I tested without putting the comma within quotes. I will simplify my actual C code.

    Would you know how to allow

    "[12, 23, 22, 4] where space chars can follow the comma or least significant digit.

    I know I can convert the commas to blanks and then use
    "[%s %s %s %s[^']' ]"

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by lsatenstein
    Would you know how to allow

    "[12, 23, 22, 4] where space chars can follow the comma or least significant digit.
    In this case, you can take advantage of the fact that whitespace before the input matched by format specifiers is optional (except for %c), so you can write: "[%1022[^,], %1022[^,], %1022[^,], %1022[^]]"
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Oct 2011
    Location
    Montreal Canada
    Posts
    6

    Thank you.

    Quote Originally Posted by laserlight View Post
    In this case, you can take advantage of the fact that whitespace before the input matched by format specifiers is optional (except for %c), so you can write: "[%1022[^,], %1022[^,], %1022[^,], %1022[^]]"
    My input string is "[....]", with either 2 or 4 digits, each in the range of 0 to 99.
    Since I know the strlen( input string), my workareas fields are not going to need to be larger than strlen( inputstring )
    I have been googling sscanf, checking man 3 info and have not seen the format I used. I came across it by chance. Still, if you have a reference to a more detailed description of sscanf(), I would sincerely appreciate having that link posted in your response.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by lsatenstein
    My input string is "[....]", with either 2 or 4 digits, each in the range of 0 to 99.
    Then I think you have two likely workable solutions:
    • Attempt a parse for 4 numbers (not digits: "12,45" would be four digits, but two numbers), and if that fails, attempt a parse for two numbers, and if that still fails, then you know the input was invalid.
    • Use strtok in a loop.

    Incidentally, instead of field1, field2, field3, etc, use an array of arrays, or if it makes sense, define a struct with more descriptive member names.

    Quote Originally Posted by lsatenstein
    I have been googling sscanf, checking man 3 info and have not seen the format I used. I came across it by chance. Still, if you have a reference to a more detailed description of sscanf(), I would sincerely appreciate having that link posted in your response.
    Your manual pages should list all the format specifiers possible, so it is unlikely that you read it carefully and yet missed the scanset format specifier. If you want the official standard description of sscanf and related functions, then you should read the C standard, or at least a late draft thereof as listed in the topic on C Draft Standards. However, the information is unlikely to be substantially different from what is present in your manual pages.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    The single quotes in your scan format are wrong. They are not being interpreted as quotes in that context. Instead they just add another character to the scanset. To put a ] (or -) in a scanset it must be the first character (after the ^ in a negated scanset). Conversely, to use ^ as a scanset character it must not be the first character.

    However, if you're just scanning for integers then %d might be better:
    Code:
    int f[4];
    char junk[256];  // indicates if any non-space garbage is present
    
    rc = sscanf(str, "[%d,%d,%d,%d]%255s", &f[0], &f[1], &f[2], &f[3], junk);
    
    if (rc == 2)
        ; // scanned two numbers
    else if (rc == 4)
        ; // scanned four numbers
    else
        ; // bad input
    Last edited by algorism; 05-08-2016 at 08:24 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 04-12-2015, 10:28 AM
  2. Extract complete integers from string
    By serge in forum C++ Programming
    Replies: 4
    Last Post: 03-15-2014, 06:26 PM
  3. reading integers with sscanf
    By freakomaniak in forum C Programming
    Replies: 1
    Last Post: 12-04-2013, 12:23 AM
  4. Reading integers in sscanf
    By Blasz in forum C Programming
    Replies: 1
    Last Post: 04-30-2010, 06:57 AM
  5. Extract numbers as integers from a string array
    By DarthC in forum C++ Programming
    Replies: 2
    Last Post: 03-23-2002, 05:09 PM

Tags for this Thread