реклама на сайте
подробности

 
 
> C18 Функция strtok
Auratos
сообщение Oct 29 2015, 13:53
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 26
Регистрация: 6-10-14
Пользователь №: 83 032



Добрый день. У меня возникла необходимость парсить большое количество строк и вычленять числа из строки, разделенные между собой точкой (например, "15.23.10"). Стал копать в эту сторону и набрел на функцию strtok, которая призвана разделять строку на подстроки, разделенные маркером, передаваемым в функцию в виде параметра. Нашел готовый пример
Код
#include <string.h>

int main()
{
    char str[] = "192.168.0.1";
    unsigned char bytes[4];
    int i = 0;

    char* buff = malloc(10);
    buff = strtok(str,".");
    while (buff != NULL)
    {
       //if you want to print its value
       printf("%s\n",buff);
       //and also if you want to save each byte
       bytes[i] = (unsigned char)atoi(buff);
       buff = strtok(NULL,".");
       i++;
    }
    free(buff);
    return 0;
}

Чуть-чуть переделал его под себя
Код
char sc[] = "150.156.16";
byte bytes[3] = "  ";
int i = 0;
char* buff;
buff = strtok(sc,(const char*)'.');
while (buff != NULL)
{
    bytes[i] = (byte)atoi(buff);
    buff = strtok(NULL,(const char*)'.');
    i++;
}

Но считывается только первое число (150), а дальше происходит выход из цикла, и я не пойму, почему. Подскажите, пожалуйста, какие условия из описания я не выполнил (P.S. ниже я привел описание функции, взятое из самого компилятора)?

Цитата
/** @name strtok
* ``A sequence of calls to the {\bf strtok} function breaks the
* string pointed to by {\bf s1} into a sequence of tokens, each of
* which is delimited by a character from the string pointed to by
* {\bf s2}. The first call in the sequence has {\bf s1} as its
* first argument, and is followed by calls with a null pointer
* as their first argument. The separator string pointed to by {\bf s2}
* may be different from call to call.
*
* ``The first call in the sequence searches the string pointed to
* by {\bf s1} for the first character that is {\it not} contained in
* the current separator string {\bf s2}. If no such character is found,
* then there are no tokens in the string pointed to by {\bf s1} and the
* {\bf strtok} function returns a null pointer. If such a character is
* found, it is the start of the first token.
*
* ``The {\bf strtok} function then searches from there for a character
* that {\it is} contained in the current separator string. If no such
* character is found, the current token extends to the end of the
* string pointed to by {\bf s1}, and subsequent searches for a token
* will return a null pointer. If such a character is found, it is
* overwritten by a null character, which terminates the current token.
* The {\bf strtok} function saves a pointer to the following character,
* from which the next search for a token will start.
*
* ``Each subsequent call, with a null pointer as the first argument,
* starts searching from the saved pointer and behaves as described
* above.
*
* ``The implementation shall behave as if no library function calls the
* {\bf strtok} function.
*
* ``This function is implemented in C, is not re-entrant and calls the
* functions: strspn, strpbrk, memchr.''
*
* @param s1 pointer to a string to begin searching, or null to continue
* searching a prior string
* @param s2 pointer to a string containing the set of separator characters
* @return ``The {\bf strtok} function returns a pointer to the first
* character of a token, or a null pointer if there is no token.''
*/
char *strtok (auto char *s1, auto const char *s2);
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Genadi Zawidowsk...
сообщение Oct 30 2015, 09:35
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Надо передавать строку с разделителями -
Код
","

а не тот кошмар что сделан (вместо запятой в мамяти по адресу 0x002d что-то конечно лежит):
Код
(const char*)'.'

В примере ведь было правильно.

Сообщение отредактировал Genadi Zawidowski - Oct 30 2015, 10:58
Go to the top of the page
 
+Quote Post
Auratos
сообщение Oct 30 2015, 10:18
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 26
Регистрация: 6-10-14
Пользователь №: 83 032



Цитата(Genadi Zawidowski @ Oct 30 2015, 09:35) *
Надо передавать строку с разделителями -
Код
","

а не тот кошмар что сделан (вместо запятой в мамяти по адресу 0x002c что-то конечно лежит):
Код
(const char*)'.'

В примере ведь было правильно.

Все верно. Я допустил эту ошибку вчера под конец рабочего дня. Сегодня утром я ее исправил, но результат не изменился. Проблема именно в том, что в цикле while совершается ровно одна итерация, после которой происходит выход из цикла. А, судя по логике, должны пройти 3 итерации. Вот моя функция
Код
void ParseDateTime(void)
{
    char date[] = "30.10.15";
    byte bytes[3] = "  ";
    int i = 0;

    char* buff;
    buff = strtok(date,(const char*)".");
    while (buff != NULL)
    {
       bytes[i] = (byte)atoi(buff);
       buff = strtok(NULL,(const char*)".");
       i++;
    }
}
Go to the top of the page
 
+Quote Post
megajohn
сообщение Oct 30 2015, 10:26
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



Цитата(Auratos @ Oct 30 2015, 14:18) *
Сегодня утром я ее исправил, но результат не изменился


наверное из-за того что массив bytes не правильно описали, и попортили стек

вот это работает

или же CRT область не определена ( ведь где то должна strtok хранить значение адреса, и по этому и нереентерабельная )


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
Auratos
сообщение Oct 30 2015, 10:45
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 26
Регистрация: 6-10-14
Пользователь №: 83 032



Цитата(megajohn @ Oct 30 2015, 10:26) *
наверное из-за того что массив bytes не правильно описали, и попортили стек

вот это работает

или же CRT область не определена ( ведь где то должна strtok хранить значение адреса, и по этому и нереентерабельная )

Byte у меня unsigned char
Код
typedef unsigned char byte;

Вот результат на выходе цикла
Прикрепленное изображение
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 01:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.01427 секунд с 7
ELECTRONIX ©2004-2016