简体   繁体   English

使用strtok()从字符串解析令牌

[英]Parse Tokens from a String using strtok()

char line[] = "COPY\tSTART\t0\tCOPY";
char *tmp;

tmp = strtok(line, "\t");
printf("%s", tmp);

This code's output is COPY . 此代码的输出为COPY And when 什么时候

char line[] = "\tSTART\t0\tCOPY";

Output is START . 输出为START

But! 但! I want to check there is nothing in front of string START. 我想检查字符串START前面是否没有内容。 That is I think \\t is first delimiter so output of strtok(line, "\\t") is NULL . 那就是我认为\\t是第一个定界符,因此strtok(line, "\\t")NULL But real output is START . 但是实际输出是START

Is there any misunderstanding? 有什么误会吗? What can I do? 我能做什么?

As per the man page of strtok() (emphasis mine) 按照strtok()手册页 (强调我的)

A sequence of two or more contiguous delimiter bytes in the parsed string is considered to be a single delimiter. 解析的字符串中两个或多个连续的定界符字节的序列被视为单个定界符。 Delimiter bytes at the start or end of the string are ignored. 字符串开头或结尾的定界符字节将被忽略。 Put another way: the tokens returned by strtok() are always nonempty strings. 换句话说,strtok()返回的令牌始终是非空字符串。

So, what you're experiencing is the right behaviour of strtok() . 因此,您正在体验的是strtok()的正确行为。

OTOH, strtok() will return NULL if there is no more tokens, so as per you have expected, returning NULL for the initial delimiter will convey wrong message and it will be confusing. OTOH,如果没有更多令牌, strtok()将返回NULL,因此,按照您的预期,为初始定界符返回NULL将传达错误消息,并且会造成混乱。 So, the bottom line is, 因此,最重要的是

  • if a token is present 如果存在令牌

    the tokens returned by strtok() are always nonempty strings. strtok()返回的令牌始终是非空字符串。

  • if a token is not present 如果不存在令牌

    strtok() will return NULL. strtok()将返回NULL。

Note: it is useful to mention that before using the retured token , always check for NULL. 注意:有必要提一下,在使用retured 令牌之前,请始终检查NULL。

What can I do? 我能做什么?

Build your own function, not exactly how strtok works but you can get some idea: 构建您自己的功能,而不是完全按照strtok工作原理,但是您可以了解一下:

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

char *scan(char **pp, char c)
{
    char *s, *p;

    p = strchr(*pp, c);
    if (p) *p++ = '\0';
    s = *pp;
    *pp = p;
    return s;
}

int main(void)
{
    char line1[] = "COPY\tSTART\t0\tCOPY";
    char line2[] = "\tSTART\t0\tCOPY";
    char *p;

    puts("Line 1");
    p = line1;
    while (p) {
        printf("%s\n", scan(&p, '\t'));
    }
    puts("Line 2");
    p = line2;
    while (p) {
        printf("%s\n", scan(&p, '\t'));
    }
    return 0;
}

Output: 输出:

Line 1
COPY
START
0
COPY
Line 2

START
0
COPY

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

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