按子字符串拆分字符串

6

我有以下字符串:

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

我想要分割文本,使用/USING=作为分隔符来获取独立的AB值。请问如何实现?我知道strtok()函数,但它只能按照单个字符进行分割。

1
您可以使用strchr查找'/''='')'字符,并使用例如strncpy(如果可以修改源字符串,则可以使用普通的strcpy)获取子字符串。 - Some programmer dude
我刚刚知道我的输入字符串中确切地包含了 /USING= 这个唯一的值,AB 只是举例,它们可能包含 \= - Ryo
1
那么使用strstr来查找子字符串的起始位置如何? - Some programmer dude
1
你可以使用strstr获取/USING的位置,并根据此位置进行分割。 - Kai Iskratsch
@Ryo,我回答了你的问题。这个问题也在另一个网站上被问到过。我的答案使用了 strtok 但仍然成功地分割了它。我甚至提到了先前提出这个问题的地方。去看看吧。 - Box Box Box Box
5个回答

9
正如其他人指出的,你可以使用来自的strstr函数在字符串中查找分隔符。然后要么复制子字符串,要么修改输入字符串以进行拆分。
下面是一个实现,返回拆分字符串的第二部分。如果无法拆分字符串,则返回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()man page我的强调):
[...] delim参数指定了一个字节集,用于分隔解析字符串中的标记。[...] 在解析字符串中,两个或多个连续的分隔符字节序列被视为单个分隔符。 [...]
因此,它不必像您提到的那样是"一个字符"。您可以使用一个字符串,比如在您的情况下使用"/USING="作为分隔符来完成任务。

1
答案无效,这将无法正确分割“U/USING=N”。 - Sebastian
@Sebastian 这更多是关于使用strtok()和所示输入的问题。如果输入不同,还有其他方法可以利用,比如strstr() - Sourav Ghosh
2
你给人的印象是使用strtok是一个好主意,而且OP会认为它可以解析其他包含/USING=的字符串。你至少应该警告他,它只适用于他的示例字符串,而不适用于任何包含子字符串/USING=的任意字符串。 - Jerry Jeremiah
@JerryJeremiah,我没有看懂你的观点。你能详细说明一下吗? - Sourav Ghosh
strtok不会根据子字符串进行分割,而是根据一组分隔符进行分割。对于在字符串中找到的每个分隔符,它都会进行分割。因此,strtok无法像你提到的那样使用子字符串进行分割。 - undefined

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;
}

-1

请查看this。这是我在谷歌上搜索您的问题时得到的结果。

对于您的情况,应该是:

#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 

如果你想检查,可以在这里在线编译和运行。


1
抱歉,但我只是针对我的实际输入字符串 char str[] = SELECT * FROM ACN WHERE CID=:C1 AND ACCTNAME=:C2/USING=(C1=70,C2='0D100S') 实现了代码,但它没有像我预期的那样工作,请帮我检查一下。 - Ryo
给我一分钟。让我编译并检查一下。 - Box Box Box Box
请问您能告诉我您得到的输出吗? - Box Box Box Box
好的,抱歉我的错误,但是你能帮我解决一下为什么我的实际字符串不起作用吗?我更喜欢使用strtok。 - Ryo
@Ryo,请给我一些时间。即使我不确定,我会回复你的。 - Box Box Box Box
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接