C语言:如何在使用strtok()一次后获取剩余的字符串

17

我的字符串是"A,B,C,D,E"
分隔符是","
如何在执行一次strtok()后获得剩余的字符串,即"B,C,D,E"

char a[] = "A,B,C,D,E";
char * separator = ",";
char * b = strtok(a,separator);
printf("a: %s\n", a);
printf("b: %s\n", b);

输出结果为:
a: A
b: A

但如何获得以下结果:
a:B,C,D,E
b:A

谢谢。


不要认为 strtok() 可以做到那样。 - Rohan
7个回答

27

您可以变更分隔符集合,只需传递一个空字符串即可:

char a[] = "A,B,C,D,E";
char * separator = ",";
char * b = strtok(a, separator);
printf("b: %s\n", b);
char * c = strtok(NULL, "");
printf("c: %s\n", c);

2
传递无分隔符是最好的选择!在我的情况下,我使用了strtok不止一次,并且在某个时候我需要剩余部分。因此,不使用strtok并不是一个解决方案。也不能通过字符求和来解决问题,因为我正在处理空格,它可能包含可变数量的连续空格等。 - Paschalis

12

不要使用strtok()来做这个,因为它并不是为这个而设计的。

使用strchr()来查找第一个分隔符,然后从那里开始:

char a[] = "A,B,C,D,E";
const char separator = ',';
char * const sep_at = strchr(a, separator);
if(sep_at != NULL)
{
  *sep_at = '\0'; /* overwrite first separator, creating two strings. */
  printf("first part: '%s'\nsecond part: '%s'\n", a, sep_at + 1);
}

非常聪明的解决方案! - Federico Ponzi

1

试试这个:

char a[] = "A,B,C,D,E";
char * end_of_a = a + strlen(a); /* Memorise the end of s. */
char * separator = ",";
char * b = strtok(a, separator);
printf("a: %s\n", a);
printf("b: %s\n", b);

/* There might be some more tokenising here, assigning its result to b. */

if (NULL != b)
{
  b = strtok(NULL, separator);
}

if (NULL != b)
{ /* Get reference to and print remainder: */
  char * end_of_b = b + strlen(b);

  if (end_of_b != end_of_a) /* Test whether there really needs to be something, 
                        will say tokenising did not already reached the end of a, 
                        which however is not the case for this example.  */
  {
    char * remainder = end_of_b + 1;
    printf("remainder: `%s`\n", remainder);
  }   
}

1

strtok会记住它上一次操作的字符串及其结束位置。要获取下一个字符串,可以再次调用该函数并将第一个参数设为NULL

char a[] = "A,B,C,D,E";
const char *separator = ",";
char *b = strtok(a, separator);
while (b) {
    printf("element: %s\n", b);
    b = strtok(NULL, separator);
}

注意:这不是线程安全的。

0

有更好的方法来处理 IP 地址,但这是一个实际的例子,需要在执行期间在某个特定点从 '.' 更改为 '/' 的分隔符。

struct Ip split_ip_by_octet(char ip_string[]) {

    struct Ip ip;
    char * value_before_delimeter = strtok(ip_string, "."); // N. 

    if (value_before_delimeter != NULL) {
        sscanf(value_before_delimeter, "%d", &ip.octet_1);
        value_before_delimeter = strtok(NULL, ".");        // n.N.

        sscanf(value_before_delimeter, "%d", &ip.octet_2);
        value_before_delimeter = strtok(NULL, ".");        // n.n.N.n/n

        sscanf(value_before_delimeter, "%d", &ip.octet_3);
        value_before_delimeter = strtok(NULL, "/");        // n.n.n.N/n

        sscanf(value_before_delimeter, "%d", &ip.octet_4);
        value_before_delimeter = strtok(NULL, "");         // n.n.n.n/N

        sscanf(value_before_delimeter, "%d", &ip.mask);
    }
    return ip; 
}

0

如果不是必须使用 strtok,你可以使用 strchr,因为分隔符只是一个单一字符:

char a[] = "A,B,C,D,E";
char *sep = strchr(a, ',');
*sep = '\0';
puts(a);
puts(sep + 1);

0
尝试一下:

printf("a: %s\n", a+1+strlen(b));


请查看larsmansdasblinkenlight的回答中关于这种方法的评论。它同样适用于你的回答。 - alk

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