【问题标题】:strtok when no data after a delimiter分隔符后没有数据时的 strtok
【发布时间】:2021-02-23 02:43:57
【问题描述】:

我需要知道两个分隔符之间什么时候没有数据,所以我在 Stack Overflow 上找到了以下 code

char *strtok_single (char * str, char const * delims)
{
  static char  *src = NULL;
  char  *p,  * ret = 0;

  if (str != NULL)
    src = str;

  if (src == NULL)
    return NULL;

  if ((p = strpbrk (src, delims)) != NULL) {
    *p  = 0;
    ret = src;
    src = ++p;

  } else if (*src) {
    ret = src;
    src = NULL;
  }

  return ret;
}

对函数进行采样

char delims[] = ",";
char data  [] = "foo,bar,,baz,biz,,";

char *p = strtok_single(data, delims);

while (p) {
  printf ("%s\n", *p ? p : "<empty>");

  p = strtok_single (NULL, delims);
}

输出

foo                                                                                                                                                                                
bar                                                                                                                                                                                
<empty>                                                                                                                                                                            
baz                                                                                                                                                                                
biz                                                                                                                                                                                
<empty>
// missing another <empty>

使用当前代码,它不会处理最后一个','之后的数据,应该还有一个空字段。我不确定如何获得正确的输出。

【问题讨论】:

  • 你为什么不实际使用strtok()
  • 提示:函数调用的语法通常像 f(...) 没有空格,而像 ifwhile 这样的结构会得到特殊处理,因此它们会脱颖而出,如 if (...) 或 @987654331 @ 带空格。隔开你的函数调用会让它们看起来很糟糕。
  • @tadman 它折叠了多个连续的分隔符。
  • @tadman:可能是因为strtok() 将多个连续的分隔符视为一个分隔符,而不是分隔多个字段。不,你不能只包装strtok() 来获得效果。您也许可以改用strsep() — 但这与strtok_single() 一样是一个非标准函数。
  • 好的;这是与我建议的不同的 SO 问题(SO 0870-5844)。尝试查看 SO 3029-4192;它可能会有所帮助。另外,请查看strsep()。我有一大块测试代码在围绕着我写来回答一个我无法识别的问题(关于 SO),所以它可能被删除了。它在工作中显示strsep(),当分隔符为, 时,它可以报告字符串",abc,def,,ghi,"(和开头的那个)末尾的空字段。这似乎就是你所追求的,不是吗?你也可以看看SO 5824-4300

标签: c strtok


【解决方案1】:

您应该使用strsep 而不是strtok。确实,strsep 支持空字段:See this answer

这是一个例子:

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

int main () {
        char delims[] = ",";
        char data  [] = "foo,bar,,baz,biz,,";
        char *p = strdup(data);
        char * tok;
        while ((tok = strsep(&p, delims)) != NULL) {
                printf ("%s\n", *tok ? tok : "<empty>");
        }
        free(p);
        return 0;
}

输出:

foo
bar
<empty>
baz
biz
<empty>
<empty>

【讨论】:

  • 这似乎是正确的解决方案。但是,在我处理我的数据的代码上是一个 csv 文件,由于某种原因,当数据来自 csv 文件时,while 循环的评估结果不正确,但我可能还有其他问题 idk。
  • @Ayelir:请注意,CSV 文件通常也可以包含带引号的字段,而这些带引号的字段可能包含逗号。例如,"abc,\"def,ghi\",jkl" 是一个 C 字符串,包含 CSV 格式的 3 个字段。中间字段用引号括起来并包含"def,ghi"。如果没有看到您的数据,很难知道这是否真的是您的问题,但您应该意识到这个问题。
  • 感谢您的提示。我的代码的问题实际上不是 csv。我没有从文件中读取每一行来更新 ptr。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
  • 1970-01-01
  • 2017-03-26
  • 1970-01-01
相关资源
最近更新 更多