2010-05-13 139 views
2

我不得不用C解析这个字符串:解析C中字符串的最简单方法是什么?

XFR 3 NS 207.46.106.118:1863 0 207.46.104.20:1863\r\n 

并能够得到207.46.106.118部分和1863部分(第一个IP地址)。

我知道我可以通过字符去char,并最终找到通过它的方式,但是,如果字符串中的IP地址可能更改为不同的格式(数字较少),那么获取此信息的最简单方法是什么?

+0

是否有可能在C中使用正则表达式? – 2010-05-13 14:48:16

+0

我不想只为这个任务使用正则表达式库。 – 2010-05-13 14:49:47

+2

最简单最准确的可能不是同一件事... – 2010-05-13 14:51:09

回答

11

您可以使用C标准库中的sscanf()。下面是如何获得的IP地址和端口的字符串,假设在地址前面的部分的示例常数:

#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以上的无效端口号将滑过)。

+0

除IP地址和端口号外的所有内容。 IP地址可能会更改(更多/更少的数字)......与端口相同。 – 2010-05-13 15:09:04

+0

@Luca:你想获得的IP地址/端口作为字符串或整数?你关心字符串的其余部分是否格式良好,或者你只对第一个IP地址感兴趣? – Christoph 2010-05-13 15:12:46

+0

是的,我需要地址/端口作为字符串。不关心其余的事情。 – 2010-05-13 15:16:46

2

取决于什么定义文档的格式。在这种情况下,它可能就像tokenizing the string一样简单,并查看所需的令牌。只需使用strtok并在空格上拆分即可获取207.46.106.118:1863,然后您可以再次对其进行标记(或仅仅手动扫描:)以获取正确的组件。

2

您可以使用strtok来标记空间中断,也可以使用scanf家族中的一个来抽出数据。

尽管存在一个很大的警告,但这些功能在安全性和错误处理方面出了问题。因人而异。

0

如果要解析的字符串格式良好,那么我会和Daniel以及Ukko的建议一起使用strtok()。

尽管警告:strtok()修改它解析的字符串。并不总是你想要的。

1

在这种情况下,strok()是微不足道的使用,将是我的选择。为了安全起见,您可以计算字符串中的':',并在有':'的情况下继续。

2

循环播放直到您找到第一个'。',然后循环播放,直到找到''。循环向前,直到找到':',每次见面都会建立子串''。'要么 ':'。您可以检查子字符串的数量和它们的长度作为简单的错误检查。然后循环,直到你找到一个'',你有1863部分。

如果字符串的开头变化不大,这将是可靠的。而且也很容易。如果字符串总是以“XFR 3 NS”开头,则可以使它更简单。

0

这可能是矫枉过正的,因为你说过你不想使用正则表达式库,但是re2c程序会为你提供正则表达式解析而无需使用库:它为C正则表达式生成DFSM。正则表达式在嵌入C代码的注释中指定。

现在看起来像是过度杀伤,如果以后你必须解析字符串的其余部分,以后可能会对你有所帮助;修改一些正则表达式来调整或添加新的语法要比修改一堆专门的标记化代码要容易得多。它使你在代码中解析得更清晰的结构。

相关问题