(C) 带有多个 spaces/tabs 的 strtok,用指针检查 null

(C) strtok with multiple spaces/tabs, checking for null with pointer

我正在尝试使用 strtok() 将字符串拆分为两个标记,字符串中可能混有空格和制表符。

所以我做了这个:

struct strstr
{
    char *str, 
         *one, 
         *two;
};

typedef struct strstr *STRSTR;

void split(STRSTR);

int main()
{
    STRSTR str = malloc(sizeof(struct strstr));
    str->str = malloc(256);

    fgets(str->str, 256, stdin);

    split(str);
    printf("%s, %s\n", str->one, str->two);

    free(str->str);
    free(str);

    return 0;
}

void split(STRSTR str)
{
    int i;
    char *temp = str->str;

    while(isspace(*(str->str)))
        str->str++;

    str->one = strtok(str->str, " \t");
    for(i = 0; i < strlen(str->one); i++)
    {
        if(!isspace(str->one[i]))
            str->str++;
    }

    str->str++;

    if(str->str != NULL)
    {
        puts("In null if");
        str->two = strtok(str->str, "");
    }

    str->str = temp;
}

所以比如你输入Hello Earth lingss,它会打印出Hello, Earth lingss,这是完美的。

但是,如果我只输入 Hello,拆分函数会进入 if(str->str != NULL) 语句。我如何阻止它使用我拥有的代码执行此操作?

编辑:还有另一个问题,如果有人不介意检查一下。 temp 只会指向 str->str 中的第一个单词。我怎样才能让它指向整个事情?

在拆分函数中的最后一个 if 块之前添加此语句

str->str = strtok(str->str," \t");喜欢

str->str = strtok(str->str," \t");
if(str->str != NULL)
{
    puts("In null if");
    str->two = strtok(str->str, "");
}

你根据 "\t" 作为分隔符拆分了字符串,但你从未更改过 str->str 字符串,使用上面的代码片段它应该可以正常工作

strtok 是一个有趣的函数,它既可以修改您传递给它的字符串,又可以在内部存储有关它的信息。您应该将您的字符串传递给 strtok 一次,然后在后续调用中传递 NULL。例如,如果您的目标是简单地将字符串分解为标记(这显然是 strtok 的目的),那么类似于:

#define BUFFER_SIZE 256
int main(void) {
    char *buffer = malloc(BUFFER_SIZE);
    if (!buffer) {
        return -1;
    }

    fgets(buffer, BUFFER_SIZE, stdin);

    char *word;
    char *ptr = buffer;
    printf("Tokens: [");
    while ((word = strtok(ptr, " \t\n"))) {
        printf("%s, ", word);
        ptr = NULL;
    }
    printf("]\n");

    free(buffer);
}

会起作用。当我 运行 这样的代码时:

./quick
when in the fun   apple         orange

我得到以下结果:

Tokens: [when, in, the, fun, apple, orange, ]

重要的是我在第一次通过循环时只将buffer指针传递给了strtok。之后它被传递为 NULL。