9

I'm running the following code in C. I'm not getting the right answer.

int main()
{

    char test[100] = "This_Is_A_Test_99";
    char tmp1[10],tmp2[10],tmp3[10],tmp4[10],tmp5[10];

    sscanf(test,"%[^'_'],%[^'_'],%[^'_'],%[^'_'],%s",tmp1,tmp2,tmp3,tmp4,tmp5);

    printf ("Temp 1 is %s\n",tmp1);
    printf ("Temp 2 is %s\n",tmp2);
    printf ("Temp 3 is %s\n",tmp3);
    printf ("Temp 4 is %s\n",tmp4);
    printf ("Temp 5 is %s\n",tmp5);

    return 0;
}

The output I get is

Temp 1 is This
Temp 2 is 
Temp 3 is 
Temp 4 is 
Temp 5 is 

What is that I have to do fetch "This" "Is" "A" "Test" and "99" on individual variables.

Kitcha
  • 1,641
  • 6
  • 19
  • 20
  • 4
    Offtopic but `%[^'_']` looked like a cute clockwork robot face! And you have four of them assembled in a line. – syockit May 12 '16 at 00:51

3 Answers3

17
sscanf(test,"%[^'_'],%[^'_'],%[^'_'],%[^'_'],%s",tmp1,tmp2,tmp3,tmp4,tmp5);

should be

sscanf(test,"%[^_]_%[^_]_%[^_]_%[^_]_%s",tmp1,tmp2,tmp3,tmp4,tmp5);

Note that you are separating the placeholders with , instead of _.

See http://ideone.com/8zBmG.

Also, you don't need the 's unless you want to skip the single quotes as well.

(BTW, you should take a look into strtok_r.)

Community
  • 1
  • 1
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • Shouldn't all specifiers have `s` at the end ? – cnicutar Nov 15 '11 at 18:30
  • 4
    @cnicutar: [No](http://pubs.opengroup.org/onlinepubs/007904975/functions/scanf.html). – kennytm Nov 15 '11 at 18:33
  • +1, but it's better be safe about arrays lenghts, and I'd test the return value: `if (sscanf(test, "%9[^_]_%9[^_]_%9[^_]_%9[^_]_%9s", tmp1, tmp2, tmp3, tmp4, tmp5) != 5) /* handle error */;` – pmg Nov 15 '11 at 18:38
5

You are scanning commata between your strings, and there are none in the text. Remove them from the pattern:

sscanf(test,"%[^'_']%[^'_']%[^'_']%[^'_']%s",tmp1,tmp2,tmp3,tmp4,tmp5);

Apostrophes are probably unnecessary, too. You don't need to quote anything since no shell is going to expand it:

sscanf(test,"%[^_]%[^_]%[^_]%[^_]%s",tmp1,tmp2,tmp3,tmp4,tmp5);

Taking up pmg's suggestion, you should write the length of your temporary explicitly into the scanf arguments to make sure you don't get buffer overflows:

sscanf(test,"%9[^_]%9[^_]%9[^_]%9[^_]%9s",tmp1,tmp2,tmp3,tmp4,tmp5);

And then check the return value:

int token_count = sscanf(test,"%9[^_]%9[^_]%9[^_]%9[^_]%9s",tmp1,tmp2,tmp3,tmp4,tmp5);
if ( token_count != 5 ) { fprintf(stderr, "Something went wrong\n"); exit(42); }
thiton
  • 35,651
  • 4
  • 70
  • 100
2

It looks to me like you have included commas (,) in your sscanf string.

But there are no commas in your input. Without any commas to process, sscanf is failing after the first string "This"

I recommend trying the format string:

"%[^_]_%[^_]_%[^_]_%[^_]_%s"
abelenky
  • 63,815
  • 23
  • 109
  • 159
  • Nor anything to match the underscores (haven't used `scanf` in a long time, but that looks odd to me). – David Thornley Nov 15 '11 at 18:30
  • @Kitcha: You should really start accepting the answers that help you out the most. Please check the "CheckMark" next to the answer that is best for each of your 7 questions. – abelenky Nov 27 '11 at 23:45