如何在不使用strok的情况下根据特定字符拆分String

时间:2018-02-17 11:51:46

标签: c string buffer token

我能够在不使用strok函数的情况下根据空间拆分字符串缓冲区。

我怎么能再次基于=符号溢出sring,因为我担心=符号后面的值。

所以逻辑是: 根据空格将字符串拆分为令牌 - >完成 然后基于=拆分每个令牌并避免使用strok - >问题在这里 登录新缓冲区后,最后只存储numric

int TokenizeString(char * s_String, char s_Token[][25], char c_Delimiter);

int main(void) {
    char buf[] = "abc=3000    Xyz=27.3   rb2act=11.82 ";

    //1.tokenizes each string without using strok
    char s_Token[15][25];
    memset(s_Token, 0, 200);

    int count = TokenizeString(buf, s_Token, ' ');
    int i;
    printf("Step 1 : Split the string  \n");

    for (i = 0; i <= count; i++) {
        printf("%s \n", s_Token[i]);
        // here is the issue , i need to store the result and spilt it again based on the = sign , i am concern about value after = sign
    }
    return EXIT_SUCCESS;
}

// Function to tokize the string without using strtok
int TokenizeString(char * s_String, char s_Token[][25], char c_Delimiter) {
    int j = 0;
    unsigned int i_Offset = 0;
    char b_Flag = 0;
    int count = 0;

    for (i_Offset = 0; i_Offset <= strlen(s_String); i_Offset++) {
        if (s_String[i_Offset] != c_Delimiter && s_String[i_Offset] != '\t' && s_String[i_Offset] != '\n' && s_String[i_Offset] != '\0') {
            s_Token[count][j] = s_String[i_Offset];
            j++;
            b_Flag = 1;
            continue;
        }

        if (b_Flag) {
            s_Token[count][j] = '\0';
            count++;
            j = 0;
            b_Flag = 0;
        }
    }
    return (count - 1);
}

2 个答案:

答案 0 :(得分:0)

我认为您需要的是在每个=之后将这些数字作为字符串并将其存储在s_Tokens中。

如果是这样,你可以做

char buf[]="abc=3000    Xyz=27.3   rb2act=11.82 ";
char *ptr=buf;
char s_Token[15][25];
int i;
for(i=0; (ptr=strchr(ptr, '='))!=NULL; )
{
        sscanf(++ptr, "%24s", s_Token[i++]);
}

您应该为错误检查做准备。

输出结果为:

3000
27.3
11.82

strchr()返回指向字符串中第一个字符的指针。如果找不到该字符,则返回NULL

答案 1 :(得分:0)

可以使用strspnstrcspn将字符串拆分为空格,并将标记存储到动态分配的指针中。
不知道每个令牌的两个部分要做什么,所以这显示了令牌,前面是相等的部分和跟随相等的双重部分。 strcspn用于在令牌中查找相等,strtod用于解析double。如果这两个部分需要存储在内存中,那么结构数组可能值得查看而不是指针。

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

char **tokenize ( char *string, char delimiter);
char **freetokens ( char **tokens);

int main ( void) {
    char buf[] = "   abc=3000    Xyz=27.3   rb2act=11.82   ";
    char **tokens = NULL;
    char *last = NULL;
    size_t each = 0;
    size_t equal = 0;
    double value = 0.0;

    tokens = tokenize ( buf, ' ');
    if ( tokens) {
        each = 0;
        while ( tokens[each]) {
            if ( ( equal = strcspn ( tokens[each], "="))) {//look for the = ( except for = in index [0])
                if ( equal < strlen ( tokens[each])) {//found an =
                    value = strtod ( tokens[each] + equal + 1, &last);//parse for a double
                    if ( last != tokens[each] + equal + 1 && *last == '\0') {//able to parse a double
                        printf ( "token\t %s\n", tokens[each]);//show the string
                        printf ( "up to =\t %.*s\n", equal, tokens[each]);//show the token up to the =
                        printf ( "double\t %f\n\n", value);//show the double
                    }
                    else {
                        printf ( "%s bad token\n\n", tokens[each]);
                    }
                }
                else {
                    printf ( "%s bad token\n\n", tokens[each]);
                }
            }
            else {
                printf ( "%s bad token\n\n", tokens[each]);
            }
            each++;
        }

        tokens = freetokens ( tokens);
    }

    return 0;
}

char **freetokens ( char **tokens) {
    size_t each = 0;

    if ( tokens) {
        while ( tokens[each]) {
            free ( tokens[each]);
            each++;
        }
        free ( tokens);
    }

    return NULL;
}

char **tokenize ( char *string, char delimiter) {
    char **lines = NULL;
    char **temp = NULL;
    char limit[2] = "";
    size_t skip = 0;
    size_t span = 0;
    size_t extent = 0;
    size_t line = 0;
    size_t len = strlen ( string);

    limit[0] = delimiter;

    if ( NULL == ( lines = malloc ( sizeof ( *lines) * 2))) {//allocate two pointers
        fprintf ( stderr, "malloc problem\n");
        return NULL;
    }
    lines[line + 1] = NULL;//sentinel

    while ( extent < len) {
        skip = strspn ( string + extent, limit);//get number of delimiters
        extent += skip;//advance past spaces
        if ( ( span = strcspn ( string + extent, limit))) {//find next delimiter or '\0'
            if ( NULL == ( lines[line] = malloc ( span + 1))) {
                fprintf ( stderr, "malloc problem\n");
                return lines;
            }
            strncpy ( lines[line], string + extent, span);
            lines[line][span] = '\0';

            if ( NULL == ( temp = realloc ( lines, sizeof ( *lines) * ( line + 3)))) {
                fprintf ( stderr, "realloc problem\n");
                return lines;
            }
            lines = temp;
            line++;
            lines[line] = NULL;
            lines[line + 1] = NULL;//sentinel
            extent += span;//advance past the token
        }
    }//loop to end of string

    return lines;
}