我需要解析来自这样的服务器的响应:
risposta:
200\n
Len 1040\n
Expire 30\n
\n
1111111111111111111111111\n
1111111111111111111111111\n
1111111111111111111111111\n
我正在尝试使用sscanf:
sscanf(risposta, "%d\nLen %d\nExpire %d\n\n%s[^\0]", &risp->type, &risp->len, &risp->expire, risp->risorsa);
但它只在risp-> risorsa中放入1111111111111111111111111。 怎么解决?
P.S。 struct risp:
typedef struct Server_risp {
int type;
int expire;
int len;
int sup;
int inf;
char risorsa[5000];
}Server_risp;
答案 0 :(得分:7)
扫描集规范不是%s[whatever]
,只是%[whatever]
,因此您的格式字符串应该更像:"%d\nLen %d\nExpire %d\n\n%[^\0]"
。
作为旁注,scanf
和朋友认为格式字符串中的任何空格都等同于任何其他空格 - 格式中的任何空格都与输入中的任意空白字符序列相匹配(并且是新的-line被认为是空格)。您当前的格式字符串可以很好地记录您期望的格式,但从它真正匹配的角度来看,您可以将其更改为:"%d Len %d Expire %d %[^\0]"
,而不会影响它的功能。特别是,你连续两个新线并没有真正实现。
编辑:考虑到这一点,[\0]
只会导致一些问题:“\ 0”会终止字符串,因此最终会出现无效的扫描设置规范。由于您只希望其余输入进入risorsa
,因此最简单的方法是使用%c
:"%d Len %d Expire %d %4999c"
。
是的,这次我实际测试了它:
#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);
}
结果:
1111111111111111111111111
1111111111111111111111111
1111111111111111111111111
编辑2:我不确定你到底遇到了什么问题。我修改了一下以显示读取前导和嵌入的空白区域:
#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);
}
......并得到了预期的结果:
| |
1111111111111111111111111
1111111111111111111111111
1111111111111111111111111
答案 1 :(得分:0)
我想指出解决问题的方法:
sscanf(risposta, "%d\nLen %d\nExpire %d\n\n%s[^\0]", &risp->type, &risp->len, &risp->expire, risp->risorsa);
代码中的问题是'\ 0'终止了右括号']'之前的字符串。你可以使用'\ 1'。然后,字符串不会过早终止,并且sscanf将继续扫描,直到它用完字符串。
更正后的代码为:
sscanf(risposta, "%d\nLen %d\nExpire %d\n\n%s[^\1]", &risp->type, &risp->len, &risp->expire, risp->risorsa);
也许这就是你想要做的第一件事。
答案 2 :(得分:-1)
以下代码存在一些问题:
sscanf(risposta, "%d\nLen %d\nExpire %d\n\n%s[^\0]", &risp->type, &risp->len, &risp->expire, risp->risorsa);
应该是:
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);
你应该处理字符串“Len”和“Expire”,而sscanf无法处理它。