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

How to split String based on specific character without using strok

我能够在不使用 strok 函数的情况下基于 space 拆分字符串缓冲区。

因为我担心 = 符号后的值,所以我如何也可以根据 = 符号再次溢出 sring。

所以逻辑是: 根据 space 将字符串拆分为标记 --> 完成 然后根据 = 拆分每个标记并避免使用 strok--> issue here 登录到新缓冲区后最终只存储数字

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] != '[=10=]') {
            s_Token[count][j] = s_String[i_Offset];
            j++;
            b_Flag = 1;
            continue;
        }

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

我想你需要的是在每个 = 之后获取这些数字作为字符串并将它们存储在 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() returns 指向字符串中某个字符第一次出现的指针。如果找不到该字符,则 returns NULL.

可以使用 strspnstrcspn 将字符串拆分为空格,并将标记存储到动态分配的指针中。
不确定每个标记的两个部分要做什么,所以这显示了标记,等于之前的部分和等于之后的双精度。 strcspn 用于查找令牌中的相等,strtod 用于解析双精度。如果这两部分需要存储在内存中,结构数组可能比指针更值得研究。

#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 == '[=10=]') {//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 '[=10=]'
            if ( NULL == ( lines[line] = malloc ( span + 1))) {
                fprintf ( stderr, "malloc problem\n");
                return lines;
            }
            strncpy ( lines[line], string + extent, span);
            lines[line][span] = '[=10=]';

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