Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/271: Рейтинг темы: голосов - 271, средняя оценка - 4.92
4 / 4 / 1
Регистрация: 22.11.2010
Сообщений: 101

Функция strtok, нужны комментарии к коду

28.03.2011, 14:30. Показов 53745. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
расскажите алгоритм
C++
1
2
3
4
5
6
7
8
9
char str[] ="- This, a sample string.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
  }
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.03.2011, 14:30
Ответы с готовыми решениями:

Нужны комментарии к коду
int bestStr(char** file, int numstr) { int iBest = -1, bestwords = 0; for (int i = 0; i < numstr; i++) { int goodwords =...

Нужны комментарии к коду
что здесь происходить double *x=new double ; double **b=new double *; for(i=0;i<n;i++) b=new double; double **a=new double...

Нужны комментарии к коду
помогите пожалуйста что и как он делает, вижу только конечный результат но хочу разобраться построчно #include <conio.h> ...

10
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
28.03.2011, 14:54
Лучший ответ Сообщение было отмечено как решение

Решение

Функция strtok вычленяет токены, разделяемые любым из символов " ,.-", из исходной строки (при этом разрушая ее). Каждый вызов strtok возвращает указатель на строку-токен, заканчивающуюся символом '\0'. Если просмотрена вся исходная строка, то функция возвращает NULL.
Следовательно, алгоритм - пока pch не равно NULL, разбиваем строку на подстроки, разделенные символами " ,.-", и печатаем эти подстроки.
strtok
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
STRTOK(3)                                        Linux Programmer's Manual                                       STRTOK(3)
 
NAME
       strtok, strtok_r - extract tokens from strings
 
SYNOPSIS
       #include <string.h>
 
       char *strtok(char *str, const char *delim);
 
       char *strtok_r(char *str, const char *delim, char **saveptr);
 
   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
 
       strtok_r(): _SVID_SOURCE || _BSD_SOURCE || _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
 
DESCRIPTION
       The  strtok()  function  parses a string into a sequence of tokens.  On the first call to strtok() the string to be
       parsed should be specified in str.  In each subsequent call that should parse the same string, str should be NULL.
 
       The delim argument specifies a set of characters that delimit the tokens in the  parsed  string.   The  caller  may
       specify different strings in delim in successive calls that parse the same string.
 
       Each  call  to  strtok() returns a pointer to a null-terminated string containing the next token.  This string does
       not include the delimiting character.  If no more tokens are found, strtok() returns NULL.
 
       A sequence of two or more contiguous delimiter characters in the parsed string is considered to be a single  delim‐
       iter.  Delimiter characters at the start or end of the string are ignored.  Put another way: the tokens returned by
       strtok() are always nonempty strings.
 
       The strtok_r() function is a reentrant version strtok().  The saveptr argument is a pointer to a  char  *  variable
       that  is  used  internally  by strtok_r() in order to maintain context between successive calls that parse the same
       string.
       On the first call to strtok_r(), str should point to the string to be parsed, and the value of saveptr is  ignored.
       In subsequent calls, str should be NULL, and saveptr should be unchanged since the previous call.
 
       Different  strings may be parsed concurrently using sequences of calls to strtok_r() that specify different saveptr
       arguments.
 
RETURN VALUE
       The strtok() and strtok_r() functions return a pointer to the next token, or NULL if there are no more tokens.
6
4 / 4 / 1
Регистрация: 22.11.2010
Сообщений: 101
28.03.2011, 15:05  [ТС]
Цитата Сообщение от Nameless One Посмотреть сообщение
Функция strtok вычленяет токены, разделяемые любым из символов " ,.-", из исходной строки (при этом разрушая ее). Каждый вызов strtok возвращает указатель на строку-токен, заканчивающуюся символом '\0'. Если просмотрена вся исходная строка, то функция возвращает NULL.
Следовательно, алгоритм - пока pch не равно NULL, разбиваем строку на подстроки, разделенные символами " ,.-", и печатаем эти подстроки.
strtok
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
STRTOK(3)                                        Linux Programmer's Manual                                       STRTOK(3)
 
NAME
       strtok, strtok_r - extract tokens from strings
 
SYNOPSIS
       #include <string.h>
 
       char *strtok(char *str, const char *delim);
 
       char *strtok_r(char *str, const char *delim, char **saveptr);
 
   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
 
       strtok_r(): _SVID_SOURCE || _BSD_SOURCE || _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
 
DESCRIPTION
       The  strtok()  function  parses a string into a sequence of tokens.  On the first call to strtok() the string to be
       parsed should be specified in str.  In each subsequent call that should parse the same string, str should be NULL.
 
       The delim argument specifies a set of characters that delimit the tokens in the  parsed  string.   The  caller  may
       specify different strings in delim in successive calls that parse the same string.
 
       Each  call  to  strtok() returns a pointer to a null-terminated string containing the next token.  This string does
       not include the delimiting character.  If no more tokens are found, strtok() returns NULL.
 
       A sequence of two or more contiguous delimiter characters in the parsed string is considered to be a single  delim‐
       iter.  Delimiter characters at the start or end of the string are ignored.  Put another way: the tokens returned by
       strtok() are always nonempty strings.
 
       The strtok_r() function is a reentrant version strtok().  The saveptr argument is a pointer to a  char  *  variable
       that  is  used  internally  by strtok_r() in order to maintain context between successive calls that parse the same
       string.
       On the first call to strtok_r(), str should point to the string to be parsed, and the value of saveptr is  ignored.
       In subsequent calls, str should be NULL, and saveptr should be unchanged since the previous call.
 
       Different  strings may be parsed concurrently using sequences of calls to strtok_r() that specify different saveptr
       arguments.
 
RETURN VALUE
       The strtok() and strtok_r() functions return a pointer to the next token, or NULL if there are no more tokens.
а как именно ,можно подробно?и что такое такены? pch = strtok (str," ,.-"); -это я понял а что дальше??

C++
1
2
3
4
5
6
pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
  }
1
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
28.03.2011, 15:20
Лучший ответ Сообщение было отмечено как решение

Решение

Zheka91, токен в данном случае - это последовательность символов исходной строки, которая ограничена символами-разделителями.
Пусть, к примеру, у нас задана строка "this is a string,divided.into-tokens". В качестве символов-разделителей у нас задана строка " ,.-", т.е. любой и этих символов будет отделять один токен от другого. Очевидно, что токенами будут: "this", "is", "a", "string", "divided", "into", "tokens".
Когда выполниться строка программы
C
1
pch = strtok (str," ,.-");
в pch будет храниться указатель на первый токен - строку "this". При этом исходная строка модифицируется (путем вставки символа '\0' вместо каждого вхождения символов-разделителей) и теперь имеет вид "is a string,divided-into.tokens". Оставшаяся часть программы представляет собой цикл, тело которого (печать очередного токена) выполняется, пока указатель pch не равен NULL. Каждый следующий вызов функции strtok будет возвращать указатель на следующий токен, модифицируя (разрушая) исходную строку. Когда исходная строка станет пустой (т.е. из строки вычленены все токены), функция strtok вернет NULL, и цикл завершится.
Все таки я посоветую прочитать кусок man'a, который я привел в предыдущем сообщении, тогда многие вопросы отпадут сами собой.
10
 Аватар для SergeyS
154 / 146 / 20
Регистрация: 12.03.2011
Сообщений: 806
26.01.2012, 16:22
Цитата Сообщение от Zheka91 Посмотреть сообщение
pch = strtok (NULL, " ,.-");
Почему тут в качестве параметра строки идет NULL? Ведь мы же работаем с исходной строкой.
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
26.01.2012, 16:23
bober94, исходная строка задается при первом вызове strtok. Во всех последующих вызовах задается нулевой указатель (в сообщении Функция strtok, нужны комментарии к коду под катом приведено описание функции)
2
 Аватар для beta-particle
4 / 4 / 1
Регистрация: 07.01.2013
Сообщений: 103
23.06.2013, 15:18
@Nameless One, а, допустим, что я хочу вывести этот так скажем "массив из слов", то что нам нужно сделать?
0
Эксперт С++
 Аватар для Thinker
4267 / 2241 / 203
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
23.06.2013, 15:25
Цитата Сообщение от Nameless One Посмотреть сообщение
При этом исходная строка модифицируется (путем вставки символа '\0' вместо каждого вхождения символов-разделителей)
не каждого, а только первого из каждой серии подряд идущих разделителей. например, если строка была такой
abc...123,,,\0 то после strtiok
она станет такой
abc\0..123\0,,\0
1
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
23.06.2013, 15:57
Цитата Сообщение от beta-particle Посмотреть сообщение
@Nameless One, а, допустим, что я хочу вывести этот так скажем "массив из слов", то что нам нужно сделать?
Я так понимаю, главный вопрос в том, как сформировать этот массив? Потому что вывод массива тривиален: в цикле для каждого элемента массива выводишь этот элемент.

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

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

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
static const char *help =
    "splitter - print tokens of SENTENCE separated by DELIMETERS\n"
    "Usage: splitter SENTENCE [DELIMETERS]\n";
 
static const char *delimeters = ",.?!():-; \t\n";
 
int main(int argc, char *argv[])
{
    char *sentence;
    char **tokens = NULL;
    char *token;
 
    size_t tokens_count = 0;
    size_t tokens_size = 0;
    size_t next_size = 4;
 
    size_t i;
 
    /* handle command-line arguments */
    switch(argc)
    {
    case 2:
        sentence = argv[1];
        break;
 
    case 3:
        sentence = argv[1];
        delimeters = argv[2];
        break;
 
    default:
        fprintf(stderr, "%s: not enough or extra arguments\n", argv[0]);
        fputs(help, stderr);
        exit(1);
    }
 
    /* split SENTENCE into an array of tokens */
    for(token = strtok(sentence, delimeters); token != NULL; token = strtok(NULL, delimeters))
    {
        if(tokens_count == tokens_size)
        {
            tokens_size = next_size;
            next_size *= 2;
            tokens = realloc(tokens, tokens_size * sizeof *tokens);
        }
 
        tokens[tokens_count++] = token; /* or `= strdup(token);` */
    }
 
    /* print the array of tokens */
    for(i = 0; i < tokens_count; ++i)
        puts(tokens[i]);
 
    if(tokens != NULL)
        free(tokens);
 
    exit(0);
}
Цитата Сообщение от Thinker Посмотреть сообщение
не каждого, а только первого из каждой серии подряд идущих разделителей
И правда. Ну, это логично, в принципе.
2
 Аватар для Argus19
1427 / 444 / 78
Регистрация: 24.09.2017
Сообщений: 2,525
Записей в блоге: 22
20.03.2020, 23:32
Nameless One, VS2010 ругается на строку 48:
" error C2440: =: невозможно преобразовать "void *" в "char **"
1> Для преобразования "void*" к указателю на тип, не являющемуся "void", требуется явное приведение"
Это возможно как-то поправить?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,217
21.03.2020, 00:14
Цитата Сообщение от SergeyS Посмотреть сообщение
Почему тут в качестве параметра строки идет NULL? Ведь мы же работаем с исходной строкой.
Именно это и означает аргумент null: "работаем с исходной строкой".

Если вы передадите не null, то это означает: "начинаем работать с новой строкой"

Добавлено через 1 минуту
Цитата Сообщение от Argus19 Посмотреть сообщение
Это возможно как-то поправить?
Вам же написали прямо в сообщении об ошибке: требуется явное приведение. Вот и приведите. Явно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.03.2020, 00:14
Помогаю со студенческими работами здесь

Нужны комментарии к коду
#include &lt;iostream&gt; using namespace std; int main() { int n, m, sum = 1, max, t; cin &gt;&gt; n; cin &gt;&gt;...

Нужны комментарии к коду
pair&lt;bool, array&lt;int, 81&gt;&gt; SOL(const char* inp) { array&lt;int, 81&gt; ANS; int* TAB = ANS.data(); int emp; int c = 0; int i, j,...

Нужны комментарии к коду
если можно расписать каждое действие #include &lt;stdlib.h&gt; #include &lt;stdio.h&gt; using namespace std; const int SIZE = 100; ...

Нужны комментарии к коду
Не могу понять что тут происходит, можете построчно объяснить? Stack* MaxStack(Stack* beg) //Нахождение...

Нужны комментарии к коду
#include &lt;iostream&gt; #include &lt;cmath&gt; using namespace std; //ЗАДАЧА #14 void print_array(int *a, int n) { for (int...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru