Вопрос

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

Может ли кто-нибудь увидеть какие-либо ограничения в этом или в любом случае я могу улучшить.

void stvstrtok(const char *source, char *dest, const char token) 
{
    /* Search for the token. */
    int i = 0;
    while(*source)
    {
        *dest++ = *source++;
        if(*source == token)
        {
            source++;
        }
    }
    *dest++ = '\0';
    }

int main(void)
{
    char *long_name = "dog,sat ,on ,the,rug,in ,front,of,the,fire";
    char buffer[sizeof(long_name)/sizeof(*long_name)];

    stvstrtok(long_name, buffer, ',');

    printf("buffer: %s\n", buffer);

   getchar();

   return 0;
}
Это было полезно?

Решение

Побочное замечание:Слово "токен" обычно используется для описания возвращаемых частей строки.Разделитель используется для описания того, что разделяет токены.Итак, чтобы сделать ваш код более понятным, вам следует переименовать token в delimiter и переименовать dest в token_dest .

Различия в вашей функции и strtok:

Есть несколько различий между вашей функцией и strtok.

  • Что делает ваша функция, так это просто удаляет разделители токенов
  • Вы вызываете свою функцию только один раз, чтобы обработать все части строки.С помощью strtok вы вызываете его несколько раз для каждой части строки (последующие разы с NULL в качестве первого параметра).
  • strtok также уничтожает исходную строку, в то время как ваш код использует свой собственный буфер (я думаю, лучше использовать свой собственный буфер, как вы это делали).
  • strtok сохраняет позицию следующего токена после каждого вызова, где первый параметр равен NULL.Затем эта позиция используется для последующих вызовов.Однако это не потокобезопасно, и ваша функция была бы потокобезопасной.
  • strtok может использовать несколько разных разделителей, в то время как ваш код использует только один.

При этом я дам предложения о том, как создать лучшую функцию, а не функцию, которая ближе к реализации strtok.

Как улучшить вашу функцию (не эмулировать strtok):

Я думаю, было бы лучше внести следующие изменения:

  • Пусть ваша функция просто вернет токен 'next'
  • Вырывайтесь из вашего цикла, когда у вас есть * source или *source == разделитель
  • Верните указатель на первый символ вашей исходной строки, которая содержит следующий токен.Этот указатель может быть использован для последующих вызовов.

Другие советы

Этот код функционирует совсем не так, как strtok().Что именно ты пытался сделать?Но что касается улучшений, то в вашем коде есть серьезная ошибка:если длина source вычитается из числа вхождений token больше, чем длина dest у вас получилось очень классическое Переполнение стека, что на данный момент кажется мне несколько ироничным.Этого не произойдет в main которым вы пользовались, но использование функции в другом месте неизбежно приведет вас на путь неуверенности и трясины отчаяния.

strtok позволяет вам перебирать все токены.Он делает это, предполагая, что исходная строка доступна для записи, и вставляя в нее нули при разрывах токена.Целевой буфер - это указатель на смещение символа внутри исходного буфера.Вы можете использовать этот факт, чтобы узнать, когда вы достигли конца + также сохраняйте "состояние" между вызовами.

Strtok - не очень хорошая функция для использования, так как она уничтожает исходную строку.Это также не повторный вход.

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

Все, что делает ваш код, из того, что я вижу, это игнорирует любой входной символ, который равен разделителю токенов, и продолжает копирование до нулевого завершения источника.

Редактировать:Кроме того, учтите, что существует два разделителя токенов последовательности:Первый будет проигнорирован вашей функцией, второй будет записан в пункт назначения, тогда как strtok() определит последовательность из 2 или более разделителей как один разделитель (справочная страница: http://man.cx/?page=strtok )

strtok уничтожает входную строку символом NUL, что делает ее своего рода враждебной.

Вам также нужно рассмотреть случай "xyz,,pdq", сколько токенов strtok извлечет из этой строки, если ',' является разделителем.

Что вы хотите, чтобы ваша функция делала в этом случае?

Кроме того, strtok(...) поддерживает несколько символов-разделителей.Ознакомьтесь с определениями strspn(...) и strcspn(...), поскольку они могут быть использованы для повторной реализации strtok(...).

Кстати, long_name - это указатель на char, а sizeof(long_name) - это sizeof(char*).не размер того, на что указывает длинное_имя.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top