безопасно пропускать нулевые терминаторы strtok

Я хочу использовать strtok, а затем вернуть строку после нулевого ограничителя, который поставил strtok.

char *foo(char *bar)
{
strtok(bar, " ");
return after_strtok_null(bar);
}
/*
examples:
foo("hello world") = "world"
foo("remove only the first") = "only the first"
*/

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

Я подробно расскажу, что я пытаюсь сделать, в конце вопроса, хотя я не думаю, что это действительно необходимо

одно решение, которое пришло мне в голову, состояло в том, чтобы просто пропустить все нулевые терминаторы, пока я не достигну ненулевого:

char *foo(char *bar)
{
bar = strtok(bar, " ");
while(!(*(bar++)));
return bar;
}

Это прекрасно работает для показанных выше примеров, но когда дело доходит до использования его для отдельных слов, я могу ошибочно идентифицировать нулевой ограничитель строки как нулевой ограничитель strtok, и тогда я могу получить доступ к невыделенной памяти.

Например, если я попробую foo("demo"\* '\0' *\), то из strtok будет "demo"\* '\0' *\, а затем, если я запущу цикл while, я буду обвинять часть после строки demo. другое решение, которое я пробовал, - это использовать strlen, но у него точно такая же проблема.

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


person avivgood2    schedule 30.07.2020    source источник
comment
Вы можете попробовать strtok(bar, " "); return strtok(NULL, "");   -  person Weather Vane    schedule 30.07.2020
comment
@WeatherVane, но тогда он вернет второе слово, а не все предложение   -  person avivgood2    schedule 30.07.2020
comment
Посмотрите на вторую строку «разделителя», которую я использовал.   -  person Weather Vane    schedule 30.07.2020
comment
@WeatherVane отличный способ сделать это!   -  person avivgood2    schedule 30.07.2020
comment
Отвечает ли это на ваш вопрос? Язык C: как получить оставшиеся строка после однократного использования strtok()   -  person Ruud Helderman    schedule 30.07.2020
comment
При передаче одного слова мой код возвращает NULL, а не пустую строку, но вы можете настроить это.   -  person Weather Vane    schedule 30.07.2020


Ответы (1)


Вместо этого вы можете использовать str[c]spn:

char *foo(char *bar) {
    size_t pos = strcspn(bar, " ");
    pos = strspn((bar += pos), "");
    // *bar = '\0';   // uncomment to mimic strtok
    return bar + pos;
}

Вы получите ожидаемую подстроку пустой строки.

Хорошо, что вы можете избежать изменения исходной строки, даже если имитация strtok тривиальна...

person Serge Ballesta    schedule 30.07.2020