-3

我有一个字符串存储在一个数组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=%[^<]<==>|D=%s||<==>S=%d",&ip_source,&ip_dest,&port_source);

但这没有用。如何在上面进行更改以修复它?

4

2 回答 2

4

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

另一个问题是message字符串会提前终止。选择一个不允许在消息中出现的字符(例如\n),并使用它%[^\n]来阅读消息。

最后,由于您正在读取固定缓冲区,因此请应用标准预防措施,并sscanf说明您的缓冲区有多大。

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

ideone 上的演示

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

于 2013-10-15T09:15:32.250 回答
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-z,A-Z和空格,您可能想试试这个:

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

编辑2:

对于其他字符串,您不能使用[^<],因为这次分隔符是|. 你应该改用这个:

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

于 2013-10-15T09:16:40.853 回答