Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
Auratos
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 59
1

C18 Функция Strtok - считывается только первое число строки

29.10.2015, 16:47. Просмотров 667. Ответов 15
Метки нет (Все метки)

Добрый день. У меня возникла необходимость парсить большое количество строк и вычленять числа из строки, разделенные между собой точкой (например, "15.23.10"). Стал копать в эту сторону и набрел на функцию strtok, которая призвана разделять строку на подстроки, разделенные маркером, передаваемым в функцию в виде параметра. Нашел готовый пример
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#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;
}
Чуть-чуть переделал его под себя
C
1
2
3
4
5
6
7
8
9
10
11
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), а дальше происходит выход из цикла, и я не пойму, почему. Подскажите, пожалуйста, какие условия из описания я не выполнил?

Описание функции из файла string.h
/** @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);
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.10.2015, 16:47
Ответы с готовыми решениями:

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

Почему с %с в scanf считывается только число
#include&lt;stdio.h&gt; main() { int intVal; char charVal; scanf(&quot;%d&quot;, &amp;intVal); ...

Считывается только первое слово из строки
Считываю строки из файла. Почему-то считывается только первое слово из строки. Помогите while (a...

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

Использование STRTOK Разбить строку на слова, из слов составить список C++ Функция strtok
Задача Дана строка слов с разделителями, в данном примере слова с пробелами Нужно, используя...

15
ValeryS
Модератор
7818 / 5817 / 758
Регистрация: 14.02.2011
Сообщений: 19,935
Завершенные тесты: 1
29.10.2015, 18:19 2
какое отношение к микроконтроллерам?
я вижу пока платформонезависимое решение
0
Kerry_Jr
Эксперт PHP
2215 / 2011 / 940
Регистрация: 14.05.2014
Сообщений: 5,873
Записей в блоге: 1
Завершенные тесты: 5
29.10.2015, 18:25 3
Цитата Сообщение от Auratos Посмотреть сообщение
C
1
(const char*)'.'
т.е. это
C
1
"."
Вам не подходит, и нужно обязательно преобразовывать символ к указателю на строку?
0
Auratos
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 59
30.10.2015, 08:05  [ТС] 4
ValeryS, Вот именно, что в VS 2010 это работает, а в MPLAB X IDE с компилятором C18 нет.

Добавлено через 2 минуты
Kerry_Jr, приходится это делать, т.к. иначе компилятор ругается на несоответствие типов
0
30.10.2015, 08:05
ValeryS
Модератор
7818 / 5817 / 758
Регистрация: 14.02.2011
Сообщений: 19,935
Завершенные тесты: 1
30.10.2015, 08:26 5
Auratos,
сравни
Цитата Сообщение от Auratos Посмотреть сообщение
buff = strtok(str,".");
и
Цитата Сообщение от Auratos Посмотреть сообщение
buff = strtok(sc,(const char*)'.');
разницу между строкой и символом знаешь?
вот описание функции
http://cppstudio.com/post/747/
Цитата Сообщение от Auratos Посмотреть сообщение
приходится это делать, т.к. иначе компилятор ругается на несоответствие типов
наверно
указатель на строку и символ
0
Auratos
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 59
30.10.2015, 09:07  [ТС] 6
ValeryS, признаюсь, я честно вчера под конец рабочего дня не заметил, что вставил символ, а не строку. Сейчас исправил - результат тот же. Ничего не изменилось. И да, я просто по интонации не понял, почему вы заулыбались после моего комментария (предполагаю, что не поверили), но если я убираю (const char*), то выдается предупреждение "Warning [2066] type qualifier mismatch in assignment"
0
gazlan
3163 / 1922 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
30.10.2015, 09:17 7
Цитата Сообщение от Auratos Посмотреть сообщение
разделенные маркером
Где это вы нашли такое описание?

strtok
separated by any of the characters that are part of delimiters
0
Auratos
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 59
30.10.2015, 09:34  [ТС] 8
gazlan, я просто выразился неправильно - символом-разделителем, в мое случае - это точка. У меня просто стоит задача разбить 2 строки дд.мм.гг и чч.мм.сс (дату и время соответственно) на 6 переменных, хранящих отдельно каждое значение. Т.е. я предполагал при помощи функции strtok разбить на подстроки, а дальше при помощи функции atoi переконвертировать эти строки в число. Не хотелось бы изобретать некрасивый велосипед, когда есть готовая функция. Вот только разобраться с ней не удается.
0
gazlan
3163 / 1922 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
30.10.2015, 09:57 9
Цитата Сообщение от Auratos Посмотреть сообщение
разобраться
ValeryS, указал вам на ошибку.

strtok использует не 'символ-разделитель', а строку-список символов.
0
ValeryS
Модератор
7818 / 5817 / 758
Регистрация: 14.02.2011
Сообщений: 19,935
Завершенные тесты: 1
30.10.2015, 10:12 10
Цитата Сообщение от Auratos Посмотреть сообщение
почему вы заулыбались после моего комментария (предполагаю, что не поверили),
поверили
но смотри что имелось в виду
например "." лежит по адресу 1000
тогда strtok(str,".");
превратится в strtok(str,1000);
а
strtok(sc,'.');
в strtok(sc,46);(код точки 46 (0x2E))но вызовет предупреждение что символ не равен указателю на строку
теперь ты насильственно приводишь
strtok(sc,(const char*)'.');
получается тоже самое, но компилятор уже уверен что нужно обращаться по адресу 46
а что там лежит??? кто знает
Цитата Сообщение от Auratos Посмотреть сообщение
Сейчас исправил - результат тот же.
приведи исправленный код
0
Auratos
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 59
30.10.2015, 10:21  [ТС] 11
ValeryS,
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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++;
    }
}
0
gazlan
3163 / 1922 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
30.10.2015, 10:30 12
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "stdafx.h"
 
#include <stdio.h>
 
static const char*   pszDate = "30.10.15";
static const char*   pszDelm = ".";
 
int main()
{
   char    pszTemp[MAX_PATH];
 
   strcpy(pszTemp,pszDate);
 
   char*   pToken = strtok(pszTemp,pszDelm);
 
   while (pToken)
   {  
      printf("%d\n",atoi(pToken));
 
      pToken = strtok(NULL,pszDelm);
   }
 
   return 0;
}
0
Миниатюры
C18 Функция Strtok - считывается только первое число строки  
ValeryS
Модератор
7818 / 5817 / 758
Регистрация: 14.02.2011
Сообщений: 19,935
Завершенные тесты: 1
30.10.2015, 10:33 13
вот это
Цитата Сообщение от Auratos Посмотреть сообщение
byte bytes[3] = " ";
Цитата Сообщение от Auratos Посмотреть сообщение
bytes[i] = (byte)atoi(buff);
обоснуй
atoi преоброзует строку в число(int)
0
Auratos
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 59
30.10.2015, 10:42  [ТС] 14
Я знаю, как работает atoi. В моем случае оно работает корректно, хотя может быть это и не эстетично. Проблема именно в том, что в цикле while совершается ровно одна итерация, после которой происходит выход из цикла. А, судя по логике, должны пройти 3 итерации
0
ValeryS
Модератор
7818 / 5817 / 758
Регистрация: 14.02.2011
Сообщений: 19,935
Завершенные тесты: 1
30.10.2015, 10:48 15
Цитата Сообщение от Auratos Посмотреть сообщение
Я знаю, как работает atoi.
тогда почему возвращаемое значение пишешь в строку

Добавлено через 1 минуту
Цитата Сообщение от Auratos Посмотреть сообщение
роблема именно в том, что в цикле while совершается ровно одна итерация,
куда указывает buff ?
0
Auratos
0 / 0 / 1
Регистрация: 07.08.2014
Сообщений: 59
30.10.2015, 11:05  [ТС] 16
ValeryS, результат первого выполнения strtok и второго
0
Миниатюры
C18 Функция Strtok - считывается только первое число строки   C18 Функция Strtok - считывается только первое число строки  
30.10.2015, 11:05
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.10.2015, 11:05

Функция разделения строки на лексемы strtok
Программе на вход подается строка, содержащая слова один-девять плюс минус, наприм: один плюс два...

Функция strtok. Представление телефонного номера в виде строки.
Запутался в функции strtok. Причем уже сделал для неё пару упражнений, вроде понимаю как она...

Первое число, состоящее только из различных цифр
Добрый день. Нужна помощь) Есть массив произвольных чисел. Нужно найти число, состоящее только...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru