Нужна помощь в функции strtok, когда первый токен равен нулю

Нужна помощь в функции strtok

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

int main()
{
    char string[100], *ptr = NULL;

    memset(string, 0, 100);
    strcpy(string, "abc#efg#xyz");

    ptr = strtok(string, "#");
    fprintf(stderr, "ptr = [%s]\n", ptr);

    ptr = strtok(NULL, "#");
    fprintf(stderr, "ptr = [%s]\n", ptr);

    ptr = strtok(NULL, "#");
    fprintf(stderr, "ptr = [%s]\n", ptr);
    return 0;
}

Выход

ptr = [abc]
ptr = [efg]
ptr = [xyz]

Это нормально, но если первый токен равен нулю, то первый вызов strtok возвращает второй токен. Насколько я понимаю, он вернет ноль при первом вызове, поскольку токен отсутствует.

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

int main()
{
    char string[100], *ptr = NULL;

    memset(string, 0, 100);
    strcpy(string, "#efg#xyz");

    ptr = strtok(string, "#");
    fprintf(stderr, "ptr = [%s]\n", ptr);

    ptr = strtok(NULL, "#");
    fprintf(stderr, "ptr = [%s]\n", ptr);

    ptr = strtok(NULL, "#");
    fprintf(stderr, "ptr = [%s]\n", ptr);
    return 0;
}***

Выход

ptr = [efg]
ptr = [xyz]
ptr = [(null)]

person neo    schedule 16.08.2013    source источник
comment
Читать: strtok()исходный код   -  person Grijesh Chauhan    schedule 16.08.2013


Ответы (2)


Согласно странице руководства strtok (от man strtok):

Последовательность из двух или более смежных символов-разделителей в анализируемой строке считается одним разделителем. Символы-разделители в начале или конце строки игнорируются. Иными словами, токены, возвращаемые функцией strtok(), всегда являются непустыми строками.

person lurker    schedule 16.08.2013
comment
Я должен был процитировать ту же самую фразу в тот же самый момент. Поздравляю, вы выиграли :-) - person Ingo Leonhardt; 16.08.2013

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

Чтобы определить начало и конец токена, функция сначала просматривает начальную позицию в поисках первого символа, не содержащегося в разделителях.

Поэтому я думаю, что это правильное поведение, которое вы видите. strtok() начинается с вашего первого символа, воспринимает его как разделитель, игнорирует его и ищет вперед первый символ без разделителя.

Я предполагаю, что способ обойти это - проверить, что первый символ не является разделителем самостоятельно.

Также проверен стандарт C (ISO/IEC 9899:1999(E)) и определение такое же:

Первый вызов в последовательности ищет в строке, на которую указывает s1, первый символ, который не содержится в текущей строке-разделителе, на которую указывает s2.

На самом деле стандарт дает пример в 7.21.5.8, пункт 8:

#include <string.h>
static char str[] = "?a???b,,,#c";
char *t;
t = strtok(str, "?"); // t points to the token "a"
person Jimbo    schedule 16.08.2013