【问题标题】:how do I parse a ',' separated char string using c?如何使用 c 解析 ',' 分隔的字符字符串?
【发布时间】:2009-12-30 04:16:08
【问题描述】:

解析逗号分隔列表的最简单方法是什么,其中每个标记之间可以有零个元素。 cstring 可能看起来像

1, 3, 4, 5, 6, 7, 8, ....

但也可能看起来像

, , , , , , , , , ...

我尝试过类似的方法:

char *original = "1, 3, 4, 5, 6, 7, 8, ...."
char *tok = strtok(original," ,")
while(tok!=NULL){
    while(*tok!='\0'){
      //dostuff
      tok++;
    }
tok=strtok(NULL," ,");
}

这显然只有在逗号之间有元素时才有效,例如我注意到如果没有元素,第一个项目列表将被跳过。

我尝试过其他解决方案,例如 strchr(),但这变得非常丑陋,我认为有更简单的方法。

谢谢

更新:

经过一些测试,我注意到“,”上的标记似乎在所有情况下都有效,除非第一项丢失。所以我把它作为一个特例来解决。

char *original = "1, 3, 4, 5, 6, 7, 8, ...."
if(*original==',')
  //dostuff    
char *tok = strtok(original,",")
while(tok!=NULL){
    while(*tok!='\0'){
      //dostuff
      tok++;
    }
tok=strtok(NULL,",");
}

感谢您的意见和帮助。 (也许我应该在发帖之前更仔细地考虑一下。)

【问题讨论】:

  • 为什么不使用任何库自己编写整个东西?

标签: c cstring delimiter strtok


【解决方案1】:

您可能需要查看非标准 strsep,它旨在替代strtok,它允许解析空字段。另请参阅Finding Tokens in a String 上的 glibc 手册章节。它可以在许多系统(各种 BSD、Linux、Mac OS X)上使用,但不是标准化的,所以我相信它可能不会出现在 Windows 或 Solaris 上。

【讨论】:

  • Brian,我认为向新手建议使用非标准函数不是一个好主意
  • 我认为指出可以满足他们需要的非标准函数是合理的,只要您包含一个警告,即它们可能并非在所有系统上都可用。我通常把它留给提出问题的人来确定我的答案是否足以满足他们的需要,只要我提供足够的信息来说明它可能存在可移植性问题。您认为我应该将警告放在答案的开头而不是结尾吗?
  • @Brian,也许让它更明显? IE。就像说“警告,这将使您的代码不可移植”。此外,由于它没有标准化,因此您无法确定它会出现在您提到的所有平台上。您假设某个环境/编译器/库,但实际上用户可以拥有不同的东西。对于标准功能和符合标准的编译器,情况并非如此。
  • 标准的问题在于,不能保证仅仅因为某些东西是标准的,它就可以使用(MSVC 中的 C99?),而且还有一些功能从未被标准化,但在每个应用程序中都可用主要平台。我发现最好担心它是否在您需要支持的平台上得到支持,而不是总是将自己限制在标准功能上。
  • MSVC 不声称与 C99 兼容。此外,我认为您假设平台 == OS,这有点误导,因为同一操作系统上可以有多个平台(编译器),并且一些编译器在多个操作系统上运行。最后,如果您希望您的程序尽可能“在任何地方”运行,那么有时唯一的方法是使用大多数平台上支持的最小子集。标准(虽然不是 C99)是这个最小值的最佳近似值
【解决方案2】:

如果您需要做的只是忽略空的“令牌”,您可以使用strspn 函数来检测仅包含空格的字符串。这是一个例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/* Is the given string whitespace only?
*/
int iswhitespace(char* s)
{
    return (strspn(s, " \t") == strlen(s));
}


int main()
{
    char line[] = "1, , 3, 4, 5, 6";
    char sep[] = ",";
    char* tok;

    tok = strtok(line, sep);

    while (tok)
    {
        if (iswhitespace(tok))
            printf("empty token\n");
        else
            printf("new token: %s\n", tok);

        tok = strtok(0, sep);
    }

    return 0;
}

这里的关键思想是仅对逗号进行标记,而不是跳过第一个元素的“,”。然后可以单独处理空格。

当然,这仍然留下了strtok 将跳过连续逗号跨度的事实。如果这对您不利,则不能使用strtok,而必须采用其他解决方案。

【讨论】:

    【解决方案3】:
    strtok cannot cannot distinguish between `,` and `,,`.
    

    【讨论】:

    • 您好,感谢您的回复,逗号后面还有一个空格,所以如果我只使用“,”作为分隔符,它仍然会跳过第一个元素。
    【解决方案4】:

    简单的for 循环怎么样?

    for (int begin = 0; original[begin]; ) {
      int end = begin;
      while (original[end] && original[end] != ',')
        ++end;
    
      // do something with original[begin] through original[end-1]
    
      begin = end;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多