我必须在C:
中解析这个字符串XFR 3 NS 207.46.106.118:1863 0 207.46.104.20:1863\r\n
能够获得207.46.106.118
部分和1863
部分(第一个IP地址)。
我知道我可以通过char查找char并最终找到它,但是获取此信息的最简单方法是什么,因为字符串中的IP地址可能会更改为不同的格式(数字更少)? / p>
答案 0 :(得分:11)
您可以使用C标准库中的sscanf()
。这是一个如何将ip和port作为字符串的示例,假设地址前面的部分是常量:
#include <stdio.h>
int main(void)
{
const char *input = "XFR 3 NS 207.46.106.118:1863 0 207.46.104.20:1863\r\n";
const char *format = "XFR 3 NS %15[0-9.]:%5[0-9]";
char ip[16] = { 0 }; // ip4 addresses have max len 15
char port[6] = { 0 }; // port numbers are 16bit, ie 5 digits max
if(sscanf(input, format, ip, port) != 2)
puts("parsing failed");
else printf("ip = %s\nport = %s\n", ip, port);
return 0;
}
格式字符串的重要部分是扫描集模式%15[0-9.]
和%5[0-9]
,它们将匹配由数字或点组成的最多15个字符的字符串(即不会检查IP地址良好的形式)和最多5位数的字符串(这意味着2 ^ 16 - 1以上的无效端口号将会漏掉)。
答案 1 :(得分:2)
取决于定义文档格式的内容。在这种情况下,它可能像tokenizing the string一样简单,并通过标记查找您想要的内容。只需使用strtok
并在空格上拆分即可获取207.46.106.118:1863
,然后您可以再次对其进行标记(或者只是手动扫描:
)以获取正确的组件。
答案 2 :(得分:2)
您可以使用strtok
来标记空格分隔,也可以使用其中一个scanf
系列来提取数据。
但是,所有这些都有一个很大的警告,这些功能因安全性和错误处理错误输入而臭名昭着。 YMMV。
答案 3 :(得分:2)
循环直到你得到第一个'。',然后循环回到找到''。循环前进,直到找到':',每次遇到'。'时都会构建子字符串。要么 ':'。您可以通过简单的错误检查来检查子串的数量及其长度。然后循环直到找到''并且你有1863部分。
如果字符串的开头变化不大,这将是强大的。而且也很容易。如果字符串始终以“XFR 3 NS”开头,则可以使其更简单。
答案 4 :(得分:1)
在这种情况下,strok()是微不足道的用途,是我的选择。为安全起见,您可以在字符串中计算“:”,如果只有一个':',则继续。
答案 5 :(得分:0)
如果要解析的字符串格式正确,那么我将使用Daniel和Ukko的建议来使用strtok()。
但是警告:strtok()修改它解析的字符串。并不总是你想要的。
答案 6 :(得分:0)
这可能有点矫枉过正,因为你说你不想使用正则表达式库,但是re2c程序会在没有库的情况下为你提供正则表达式解析:它为正则表达式生成DFSM作为C代码。正则表达式在C代码中嵌入的注释中指定。
如果你必须解析其余的字符串,现在看起来像矫枉过正的话可能会让你感到安慰。修改一些正则表达式以调整或添加新语法比修改一堆ad hoc标记化代码要容易得多。它使您在代码中解析的内容结构更加清晰。