我有一个字符串存储在名为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);
但是没有用。如何改变以上来解决它?
答案 0 :(得分:4)
问题是第一个%s
不知道停在哪里。替换为%[^<]
以修复。
另一个问题是message
字符串会提前终止。选择邮件中不允许的字符(例如\n
),然后使用%[^\n]
阅读邮件。
最后,由于您正在阅读固定缓冲区,请应用标准预防措施,并告诉sscanf
缓冲区有多大。
sscanf(decrypted, "%19[^<]<==>%d<==>%999[^\n]", ip_source, &port_source, message);
通常,如果您的字符串具有固定的分隔符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-z
,A-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
同样如此。