按子字符串分割字符串

问题描述 投票:0回答:6

我有以下字符串:

char str[] = "A/USING=B)";

我想拆分以获得单独的

A
B
值,并以
/USING=
作为分隔符

我该怎么做?我知道

strtok()
但它只是被一个字符分割为分隔符。

c string tokenize strtok
6个回答
9
投票

正如其他人指出的那样,您可以使用

strstr
中的
<string.h>
来查找字符串中的分隔符。然后复制子字符串或修改输入字符串以将其拆分。

这是一个返回分割字符串的第二部分的实现。如果字符串无法分割,则返回

NULL
并且原始字符串不变。如果需要将字符串分割成更多的子字符串,可以重复调用尾部的函数。第一部分是输入字符串,可能会缩短。

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

char *split(char *str, const char *delim)
{
    char *p = strstr(str, delim);

    if (p == NULL) return NULL;     // delimiter not found

    *p = '\0';                      // terminate string after head
    return p + strlen(delim);       // return tail substring
}

int main(void)
{
    char str[] = "A/USING=B";
    char *tail;

    tail = split(str, "/USING=");

    if (tail) {
        printf("head: '%s'\n", str);
        printf("tail: '%s'\n", tail);
    }

    return 0;
}

1
投票

我知道

strtok()
,但它只是被一个字符分割为分隔符

不,不是。

根据strtok()

手册页
,(强调我的

char *strtok(char *str, const char *delim);

[...]

delim
参数指定一组字节集,用于分隔已解析字符串中的标记。 [...] 已解析字符串中两个或多个连续分隔符字节的序列被视为单个分隔符。 [...]

因此,它不必是您提到的“一个字符”。您可以使用字符串(如您的情况

"/USING="
)作为分隔符来完成工作。


1
投票

这里有一个小函数可以做到这一点。它的工作方式与 strtok_r 完全相同,只是分隔符被视为分隔字符串,而不是分隔字符列表。

char *strtokstr_r(char *s, char *delim, char **save_ptr)
{
    char *end;
    if (s == NULL)
        s = *save_ptr;

    if (s == NULL || *s == '\0')
    {
        *save_ptr = s;
        return NULL;
    }

    // Skip leading delimiters.
    while (strstr(s,delim)==s) s+=strlen(delim);
    if (*s == '\0')
    {
        *save_ptr = s;
        return NULL;
    }

    // Find the end of the token.
    end = strstr (s, delim);
    if (end == NULL)
    {
        *save_ptr = s + strlen(s);
        return s;
    }

    // Terminate the token and make *SAVE_PTR point past it.
    memset(end, 0, strlen(delim));
    *save_ptr = end + strlen(delim);
    return s;
}

0
投票

老兄,这个答案只有在输入是这个时才有效,如果是“abUcd/USING=efgh”,你的算法就不起作用。

这个答案对我来说是唯一有效的:

char *split(char *str, const char *delim)
{
    char *p = strstr(str, delim);

    if (p == NULL) return NULL;     // delimiter not found

    *p = '\0';                      // terminate string after head
    return p + strlen(delim);       // return tail substring
}

int main(void)
{
    char str[] = "A/USING=B";
    char *tail;

    tail = split(str, "/USING=");

    if (tail) {
        printf("head: '%s'\n", str);
        printf("tail: '%s'\n", tail);
    }

    return 0;
}

0
投票

strtok
采用 分隔符列表,因此它仅按每个字符而不是整个分隔符字符串进行分割。这意味着
"___"
的分隔符将在字符串中的
"_"
"__"
"___"
...等处拆分,因为它使用一个下划线作为分隔符。

示例:

int main ()
{
  char str[] ="- This, a sample string with-dash-es.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.---");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.---");
  }
  return 0;
}

输出:

Splitting string "- This, a sample string with-dash-es." into tokens:
This
a
sample
string
with
dash
es

如果你想分割整个子字符串,

strstr
将是一个不错的选择,就像其他提到的那样。下面是我多次分割字符串(而不是一次)的两分钱:

int main(void)
{
    char str[] = "This is an-example string---to---be-split.";
    char *start = str;
    char *end;

    end = strstr(start, "---");
    while (end) {
      *end = '\0';
      printf("part: '%s'\n", start);
      start = end + strlen("---");
      end = strstr(start, "---");
    }
    
    printf("last part: '%s'\n", start);

    return 0;
}

输出:

part: 'This is an-example string'
part: 'to'
last part: 'be-split.'

-1
投票

参见这个。当我在谷歌上搜索你的问题时我得到了这个。

就您而言,它将是:

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

int main (int argc, char* argv [])
{
    char theString [16] = "abcd/USING=efgh";
    char theCopy [16];
    char *token;
    strcpy (theCopy, theString);
    token = strtok (theCopy, "/USING=");
    while (token)
    {
        printf ("%s\n", token);
        token = strtok (NULL, "/USING=");
    }

    return 0;
}

这使用

/USING=
作为分隔符。

其输出是:

abcd                                                                                                                                                                                                                      
efgh 

如果你想检查,你可以通过这里在线编译并运行它。

© www.soinside.com 2019 - 2024. All rights reserved.