在C中解析字符串最简单的方法是什么?

时间:2010-05-13 14:47:06

标签: c parsing

我必须在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>

7 个答案:

答案 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标记化代码要容易得多。它使您在代码中解析的内容结构更加清晰。