2015-03-13 50 views
0

我使用的功能是was posted as an answer on another Stackoverflow question。发布此的用户请注意:it does not handle consecutive delimiters如何修改字符串拆分函数以忽略连续分隔符?

我想知道如何修改它,以便它可以处理连续的分隔符?当我有一个额外的delminator时,我基本上忽略它。

例如说我有这样的事情:

h2,3 d3,4 j3,3 y4,1 g4,3

我想这个分成每个空间的字符串数组,但你可以在某些情况下,看到里面有多个空格。我只是想忽略额外的分隔符。

编辑:只是要清楚,这是我从我挂到上面的答案使用的代码:

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

char** str_split(char* a_str, const char a_delim) 
{ 
    char** result = 0; 
    size_t count  = 0; 
    char* tmp  = a_str; 
    char* last_comma = 0; 
    char delim[2]; 
    delim[0] = a_delim; 
    delim[1] = 0; 

    /* Count how many elements will be extracted. */ 
    while (*tmp) 
    { 
     if (a_delim == *tmp) 
     { 
      count++; 
      last_comma = tmp; 
     } 
     tmp++; 
    } 

    /* Add space for trailing token. */ 
    count += last_comma < (a_str + strlen(a_str) - 1); 

    /* Add space for terminating null string so caller 
     knows where the list of returned strings ends. */ 
    count++; 

    result = malloc(sizeof(char*) * count); 

    if (result) 
    { 
     size_t idx = 0; 
     char* token = strtok(a_str, delim); 

     while (token) 
     { 
      assert(idx < count); 
      *(result + idx++) = strdup(token); 
      token = strtok(0, delim); 
     } 
     assert(idx == count - 1); 
     *(result + idx) = 0; 
    } 

    return result; 
} 

int main() 
{ 
    char months[] = "JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC"; 
    char** tokens; 

    printf("months=[%s]\n\n", months); 

    tokens = str_split(months, ','); 

    if (tokens) 
    { 
     int i; 
     for (i = 0; *(tokens + i); i++) 
     { 
      printf("month=[%s]\n", *(tokens + i)); 
      free(*(tokens + i)); 
     } 
     printf("\n"); 
     free(tokens); 
    } 

    return 0; 
} 
+0

视情况而定,忽略可能不是正确的方法。顺序中的两个分隔符只意味着它们之间有一个空字符串。 – Havenard 2015-03-13 19:49:37

+0

@Havenard这是'strsep()'不同的地方吗?使用适当的功能。 – 2015-03-13 19:50:52

回答

2

T他应该做的伎俩:如果你想让它禁用测序分隔符overruning

char** str_split(const char *str, char delimiter) 
{ 
    int len, i, j; 
    char* buf; 
    char** ret; 

    len = strlen(str); 
    buf = malloc(len + 1); 
    memcpy(buf, str, len + 1); 

    j = 1; 
    for (i = 0; i < len; ++i) 
     if (buf[i] == delimiter) 
     { 
      while (buf[i + 1] == delimiter) i++; 
      j++; 
     } 

    ret = malloc(sizeof(char*) * (j + 1)); 
    ret[j] = NULL; 

    ret[0] = buf; 
    j = 1; 
    for (i = 0; i < len; ++i) 
     if (buf[i] == delimiter) 
     { 
      buf[i] = '\0'; 
      while (buf[i + 1] == delimiter) i++; 
      ret[j++] = &buf[i + 1]; 
     } 
    return ret; 
} 

下降两行while (buf[i + 1] == delimiter) i++;

+0

请问你为什么在输入字符串中使用'const'? – ComputerLocus 2015-03-13 20:55:15

+0

@Fogest这意味着这个函数可以和字符串一起使用。它不会修改您提供的缓冲区。 – Havenard 2015-03-13 21:44:39

0

我觉得strtok()能够处理您的要求。来自man page

被解析的字符串中的两个或多个连续分隔符字节的序列被认为是单个分隔符。

+0

你看过我实际使用的代码吗?因为它已经使用strtok .... – ComputerLocus 2015-03-13 20:03:20

1

将投巨资在回答你的问题,SO说:注意到它不处理连续分隔符,“JAN ,,,二月,三月” - 但没有证实的贡献者的评论。

功能strsep()对待连续的分隔符作为含有空字段,但功能strtok()忽略(的任意组合)的分隔符集的多个实例。随着MSVC,我得到这个程序

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

int main(void) 
{ 
    char months[]= "JAN, ,\t , ,FEB,MAR"; 
    char seps[] = ", \t\r\n"; 
    char *sptr; 
    sptr = strtok(months, seps); 
    while (sptr) { 
     printf ("Month is: %s\n", sptr); 
     sptr = strtok(NULL, seps); 
    } 
    return 0; 
} 

输出:

Month is: JAN 
Month is: FEB 
Month is: MAR 

在您的具体的例子(我怀疑可能包含标签),这将是

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

int main(void) 
{ 
    char stuff[]= "h2,3  d3,4 j3,3 y4,1 g4,3"; 
    char seps[] = " \t"; 
    char *sptr; 
    sptr = strtok(stuff, seps); 
    while (sptr) { 
     printf ("Stuff is: %s\n", sptr); 
     sptr = strtok(NULL, seps); 
    } 
    return 0; 
} 

输出:

Stuff is: h2,3 
Stuff is: d3,4 
Stuff is: j3,3 
Stuff is: y4,1 
Stuff is: g4,3 
+0

所以你说我应该使用这个代码呢?因为我试图将每个元素存储到一个数组中。使用我提供的示例数据行我应该得到一个数组,如下所示:'[“h2,3”,“d3,4”,“j3,3”,“y4,1”,“g4,3”]' – ComputerLocus 2015-03-13 20:15:51

+0

添加了您的具体示例。 – 2015-03-13 20:16:54

+0

在那里没有看到它? – ComputerLocus 2015-03-13 20:22:23

相关问题