Sscanf & newlines

I need to parse the response from the server as follows:

risposta:

200\n Len 1040\n Expire 30\n \n 1111111111111111111111111\n 1111111111111111111111111\n 1111111111111111111111111\n 

I am trying to use sscanf:

 sscanf(risposta, "%d\nLen %d\nExpire %d\n\n%s[^\0]", &risp->type, &risp->len, &risp->expire, risp->risorsa); 

but it only puts 1111111111111111111111111 in risp-> risorsa. How to allow?

Ps struct risp:

 typedef struct Server_risp { int type; int expire; int len; int sup; int inf; char risorsa[5000]; }Server_risp; 
+8
c newline eof scanf
source share
3 answers

The scan specification is not %s[whatever] , it's just %[whatever] , so your format string should look more like: "%d\nLen %d\nExpire %d\n\n%[^\0]" .

As a side note, scanf and the other side consider that any empty space in the format string is equivalent to any other space - any spaces in the format correspond to an arbitrary sequence of space characters at the input (and a new line is considered a space). Your current format string is well documenting the format you expect, but in terms of what it really matches, you can change it to something like: "%d Len %d Expire %d %[^\0]" without affecting what he will do. In particular, your two consecutive newlines are not really up to the mark.

Edit: thinking about this, [\0] causes only a small problem: "\ 0" ends the line, so you get an invalid specification for scanning. Since you just want the rest of the input to risorsa to risorsa , it might be easiest to use %c : "%d Len %d Expire %d %4999c" .

And yes, this time I really tested it:

 #include <stdio.h> char *riposta = "200\n"  "Len 1040\nExpire 30\n"  "\n1111111111111111111111111\n"  "1111111111111111111111111\n"  "1111111111111111111111111\n"; typedef struct Server_risp {  int type;  int expire;  int len;  int sup;  int inf;  char risorsa[5000]; }Server_risp; int main() {  Server_risp risp;  sscanf(riposta, "%d Len %d Expire %d %4999c", &risp.type, &risp.len, &risp.expire, risp.risorsa);  printf("%s\n", risp.risorsa); } 

result:

 1111111111111111111111111 1111111111111111111111111 1111111111111111111111111 

Edit 2: I'm not sure exactly what the problem you're working with. I modified it a bit to show both the leading and the built-in white space:

 #include <stdio.h> char *riposta = "200\n" "Len 1040\nExpire 30\n" "| |" "\n1111111111111111111111111\n" "1111111111111111111111111\n" "1111111111111111111111111\n"; typedef struct Server_risp { int type; int expire; int len; int sup; int inf; char risorsa[5000]; }Server_risp; int main() { Server_risp risp; sscanf(riposta, "%d Len %d Expire %d%4999c", &risp.type, &risp.len, &risp.expire, risp.risorsa); printf("%s\n", risp.risorsa); } 

... and got pretty much the expected result:

 | | 1111111111111111111111111 1111111111111111111111111 1111111111111111111111111 
+7
source share

I would like to indicate a way to solve the problem:

 sscanf(risposta, "%d\nLen %d\nExpire %d\n\n%s[^\0]", &risp->type, &risp->len, &risp->expire, risp->risorsa); 

the problem in the code is that '\ 0' ends the line before the closing bracket ']'. You can use '\ 1'. Then the line is not interrupted prematurely, and sscanf will continue scanning until the line ends.

Corrected Code:

 sscanf(risposta, "%d\nLen %d\nExpire %d\n\n%s[^\1]", &risp->type, &risp->len, &risp->expire, risp->risorsa); 

Perhaps this is exactly what you wanted to do in the first place.

0
source share

There are some problems with the following code:

 sscanf(risposta, "%d\nLen %d\nExpire %d\n\n%s[^\0]", &risp->type, &risp->len, &risp->expire, risp->risorsa); 

It should be:

 char tmp_str[100]; sscanf(risposta, "%d %s %d %s %d %s[^\0]", &risp->type, tmp_str, &risp->len, tmp_str, &risp->expire, risp->risorsa); 

You must process the lines "Len" and "Expire", and sscanf cannot process it.

-one
source share

All Articles