再记一下sscanf的一个小问题

正在进行的项目中有个网络传输模块,需要在设备端将上位机发送的XML命令解析出来并转发到其它模块。在我测试一个获取数据的命令时,发现上位机读取到的数据是错误,看XML命令格式,明明是对的,但读到的数据就是不正确,肯定有问题。因为网络传输模块在其它项目一直使用,一直OK,现在出问题了,很郁闷。于是使出printf大法跟踪、终于找到问题原因。原来,又是sscanf搞的问题。记得小弟刚来这家公司时接手前人写的ftp模块,里面大量用了sscanf,还专门写了篇文章。现在又遇到了。

这个XML命令是自定义的,格式类似:大人[1],大奔[黄],大小[250],中括号表示为传递的参数,其中既有数字(%d)也有字符串(%s),一开始还以为是中文搞的鬼,后来查发现是只要是字符中在命令的中间,使用sscanf的%s就会将该字符串及以后的所有的字符都解析到,因此,字符串后面的数据就不正确了。
一开始想着使用字符串查找strchr逐个字符来查找、确定每一个参数,但那个命令一共有20多个参数,这点我是不能接受的。后来再调试一下,发现只要将有字符串的参数放到最后就可以了。至于最后有个右中括号,则可以将它直接写’0’来解决。
不过这种方法,只能适用于只有一个字符串的情况。如果复杂的情况,最终的方法是重新制定命令的格式。
示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void sscanf_test()
{
    char* buff = "wo:[12],ni:[25],ta:[中文我顶]";
    char wo[32] = {0};
    char ni[32] = {0};
    char ta[32] = {0};
    char buffer[128] = {0};
    int wo1, ni1, ta1;
    printf("test1:\n");
    sscanf(buff, "wo:[%d],ni:[%d],ta:[%s]", &wo1, &ni1, ta);
    printf("output1:wo: %d \nni: %d \nta: %s\n", wo1, ni1, ta);

    char* buff1 = "wo:[12],ni:[结束了还来],ta:[250]";
    printf("test2:\n");
    sscanf(buff1, "wo:[%d],ni:[%s],ta:[%d]", &wo1, ni, &ta1);
    printf("output2:wo: %d\nni: %s \nta: %d\n", wo1, ni, ta1);
}

输出:

1
2
3
4
5
6
7
8
test1:
output1:wo: 12
ni: 25
ta: 中文我顶]
test2:
output2:wo: 12
ni: 结束了还来],ta:[250]
ta: 7 // 此处已是错误的了

李迟 2015年1月18日 周日 下午