适当的sscanf使用麻烦

时间:2013-10-15 09:10:33

标签: c string gcc printf scanf

我有一个字符串存储在名为decrypted的数组中,如下所示:

char decrypted[5000];
sprintf(decrypted,"%s","192.168.0.2<==>6060<==>this is ipsec data");

我正在尝试使用sscanf读取此内容,如下所示:

char ip_source[20];
int port_source;
char message[1000];

 sscanf(decrypted,"%s<==>%d<==>%s",ip_source,&port_source,message);
 printf("source = %s\nport = %d\nmessage = %s\n",ip_source,port_source,message);

但这似乎不起作用我得到以下输出:

source = 192.168.0.2<==>6060<==>this
port = 0
message =

我做错了什么?我该如何解决?

修改

根据以下建议,以下是我更改代码的方法,这是新输出:

char decrypted[5000];
sprintf(decrypted,"%s","192.168.0.2<==>6060<==>this is ipsec data");

char ip_source[20];
int port_source;
char message[1000];

 sscanf(decrypted,"%[^<]<==>%d<==>%s",ip_source,&port_source,message);

 printf("source = %s\nport = %d\nmessage = %s\n",ip_source,port_source,message); 

输出:

source = 192.168.0.2
port = 6060
message = this

如何将消息作为完整字符串读取而不是在第一个空格处停止?

编辑2:

我可以稍微放纵一下好人吗?

这是我想读的另一个字符串:

sprintf(decrypted,"%s","S=192.168.0.2|D=192.168.0.4||<==>S=6060");
sscanf(decrypted,"S=%s|D=%s||<==>S=%d",&ip_source,&ip_dest,&port_source);

它再次造成问题。我试图暗示你的解决方案试图解决它如下:

的sscanf(解密, “S =%[^&LT;]&LT; ==&GT; | d =%S ||&LT; ==&GT; S =%d”,&安培; ip_source,&安培; ip_dest,&安培; port_source);

但是没有用。如何改变以上来解决它?

2 个答案:

答案 0 :(得分:4)

问题是第一个%s不知道停在哪里。替换为%[^<]以修复。

另一个问题是message字符串会提前终止。选择邮件中不允许的字符(例如\n),然后使用%[^\n]阅读邮件。

最后,由于您正在阅读固定缓冲区,请应用标准预防措施,并告诉sscanf缓冲区有多大。

sscanf(decrypted, "%19[^<]<==>%d<==>%999[^\n]", ip_source, &port_source, message);

Demo on ideone

通常,如果您的字符串具有固定的分隔符x,请在%[^x]格式说明符中使用该分隔符。因此"S=%s|D=%s||<==>S=%d"格式字符串变为"S=%19[^|]|D=%19[^|]||<==>S=%d"

答案 1 :(得分:2)

sscanf(decrypted,"%s<==>%d<==>%s",ip_source,&port_source,message);

scanf中,%s会消耗默认情况下不被视为空格的每个字符。这就是您在192.168.0.2<==>6060<==>this中获得source的原因。

您可以通过更改scanf认为的分隔符来解决此问题:

sscanf(decrypted,"%[^<]<==>%d<==>%s",ip_source,&port_source,message);

修改

同样的规则也适用于message中存储的内容。假设message只能包含集a-zA-Z和空格中的字符,您可能需要尝试此操作:

sscanf(decrypted,"%[^<]<==>%d<==>%[A-Za-z ]",ip_source,&port_source,message);

<强> EDIT2:

对于其他字符串,您无法使用[^<],因为此时分隔符为|。你应该改用它:

sscanf(decrypted,"S=%[^|]|D=%[^|]||<==>S=%d",ip_source,ip_dest,&port_source);

此外,&ip_source&ip_dest会出错,因为它们被定义为字符数组 - 您不需要引用运算符。

最后,考虑在缓冲区中添加限制检查,如其他答案中所述:

sscanf(decrypted,"%19[^<]<==>%d<==>%999[a-z]",ip_source,&port_source,message);

第二个scanf同样如此。