【问题标题】:What's the easiest way to parse a string in C?在 C 中解析字符串的最简单方法是什么?
【发布时间】:2010-05-13 14:47:05
【问题描述】:

我必须在 C 中解析这个字符串:

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

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

我知道我可以逐个字符地查找并最终找到我的方法,但鉴于字符串中的 IP 地址可能会更改为不同的格式(位数更少),获取此信息的最简单方法是什么?

【问题讨论】:

  • 是否可以在 C 中使用正则表达式?
  • 我不想只为这个任务使用正则表达式库。
  • 最简单和最准确的可能不是一回事...

标签: c parsing


【解决方案1】:

您可以使用 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 以上的无效端口号将通过)。

【讨论】:

  • 除 IP 地址和端口号之外的所有内容。 IP 地址可能会改变(更多/更少的数字)...与端口相同。
  • @Luca:你想获取 IP 地址/端口作为字符串还是整数?您是否关心字符串的其余部分是否格式正确,或者您只对第一个 IP 地址感兴趣?
  • 是的,我需要两个地址/端口作为字符串。其他的不用管。
  • @Christoph:+1。 scanf 的用法非常好。你能解释一下它是如何工作的吗?
  • 非常感谢。正是我想要的。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    您可以使用strtok 来标记空间中断,或者您也可以使用scanf 系列之一来提取数据。

    所有这一切都有一个很大的警告,这些函数因安全性和错误处理错误输入而臭名昭著。 YMMV。

    【讨论】:

      【解决方案4】:

      循环直到你得到第一个'.',然后循环回来直到你找到''。循环向前直到找到 ':',每次遇到 '.' 时都会构建子字符串。或者 ':'。您可以检查子字符串的数量及其长度作为简单的错误检查。然后循环直到你找到一个 ' ' 并且你有 1863 部分。

      如果字符串的开头变化不大,这将是健壮的。而且也很容易。如果字符串 always 以“XFR 3 NS”开头,您可以使其更简单。

      【讨论】:

        【解决方案5】:

        在这种情况下,strok() 的用处不大,是我的选择。为了安全起见,您可以计算字符串中的 ':',如果正好有一个 ':',则继续。

        【讨论】:

          【解决方案6】:

          如果要解析的字符串格式正确,那么我会接受 Daniel 和 Ukko 的建议,使用 strtok()。

          不过有一点警告:strtok() 修改了它解析的字符串。并不总是你想要的。

          【讨论】:

            【解决方案7】:

            这可能有点矫枉过正,因为您说您不想使用正则表达式库,但是 re2c 程序会在没有库的情况下为您提供正则表达式解析:它为 C 代码生成正则表达式的 DFSM。正则表达式在 C 代码中嵌入的 cmets 中指定。

            如果你必须解析字符串的其余部分,现在看起来有点过分的东西可能会成为你的安慰;修改一些正则表达式来调整或添加新语法比修改一堆临时标记化代码要容易得多。它使您在代码中解析的结构更加清晰。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-09-05
              • 2011-03-13
              • 2011-02-08
              • 2011-08-22
              • 2013-07-06
              • 1970-01-01
              • 1970-01-01
              • 2012-07-28
              相关资源
              最近更新 更多