简体   繁体   English

如何使用strtok_r标记包含空值的字符串

[英]How to tokenize a string containing null values using strtok_r

I have a string which contains some comma separated values. 我有一个字符串,其中包含一些逗号分隔值。 The value may or may not be NULL. 该值可能为NULL,也可能不为NULL。 like : 喜欢 :

strcpy(result, "Hello,world,,,wow,");

I want null values to be printed accepted too. 我也想要接受打印的空值。 How can I proceed while using strtok_r which gives me NULL values too. 如何在使用strtok_r时继续执行,这也给出了NULL值。

I tried this : 我试过这个:

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

int main(void) {

    char result[512] = { 0 };
    strcpy(result, "Hello,world,,,wow");
    char *token, *endToken;
    int i = 0;
    token = strtok(result, ",");
    while (i < 5) {
        printf("%d\n", ++i);
        printf("%s\n", token);
        token = strtok(NULL, ",");
    }
    return 0;
}

and the output is : 输出是:

1
Hello
2
world
3
wow
4
Segmentation fault (core dumped)

I know why it is giving Segmentation fault. 我知道它为什么会出现Segmentation故障。 I want the solution so that output is like: 我想要解决方案,以便输出如下:

1
Hello
2
World
3
*
4
*
5
wow

I want * to be printed for the null tokens but null tokens are not even extracted. 我希望*为空标记打印,但是甚至不提取空标记。

From strtok_r man page: 来自strtok_r手册页:

A sequence of two or more contiguous delimiter characters in the parsed string is considered to be a single delimiter. 解析后的字符串中的两个或多个连续分隔符字符的序列被视为单个分隔符。

So it won't work in your case. 所以它不适合你的情况。 But you can use code like this one: 但你可以使用这样的代码:

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

int main(void) {
    int i = 0;
    char result[512];
    char *str = result, *ptr;
    strcpy(result, "Hello,world,,,wow");
    while (1) {
        ptr = strchr(str, ',');
        if (ptr != NULL) {
            *ptr = 0;
        }
        printf("%d\n", ++i);
        printf("%s\n", str);
        if (ptr == NULL) {
            break;
        }
        str = ptr + 1;
    }
    return 0;
}

If you don't have strsep() you can roll your own. 如果你没有strsep()你可以自己动手。

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

int main(void) {

    char result[512] = "Hello,world,,,wow";
    char *token, *endToken;
    int i = 0;

    token = result;
    do {
        endToken = strchr(token, ',');
        if (endToken)
            *endToken = '\0';           // terminate token
        printf("%d\n", ++i);
        if (*token == '\0')             // substitute the empty string
            printf("*\n");
        else
            printf("%s\n", token);
        if (endToken)
            token = endToken + 1;
    } while (endToken);
    return 0;
}

Program output: 节目输出:

1
Hello
2
world
3
*
4
*
5
wow

For strtok to find a token, there must be a first character that is not a delimiter. 要使strtok找到令牌,必须有第一个不是分隔符的字符。 It only returns NULL when it reaches the end of the string, ie when it finds the '\\0' character. 它只在到达字符串末尾时返回NULL,即当它找到'\\0'字符时。

To determine the beginning and the end of a token, the function first scans from the starting location for the first character not contained in delimiters (which becomes the beginning of the token) . 为了确定令牌的开始和结束,该函数首先从起始位置扫描未包含在分隔符中第一个字符(它成为令牌的开头) And then scans starting from this beginning of the token for the first character contained in delimiters, which becomes the end of the token. 然后从令牌的开头开始扫描包含在分隔符中的第一个字符,这将成为令牌的结尾。 The scan also stops if the terminating null character is found. 如果找到终止空字符,扫描也会停止。

http://www.cplusplus.com/reference/cstring/strtok http://www.cplusplus.com/reference/cstring/strtok

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM