Strtok_s Где Можно Посмотреть Сам Принцип Функции

Тема в разделе "Общие вопросы по С и С++", создана пользователем abyss, 20 фев 2014.

  1. abyss

    abyss Member

    Регистрация:
    5 сен 2013
    Сообщения:
    8
    Симпатии:
    0
    на этой странице http://translate.google.com/translate?lang...y/ftsafwz3.aspx

    написана не вся информация которая интересует, с\меня интересуют принципы а не общие формулировки
    где или кто может их показать приметно следующее:

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

    у кого есть такая информация??!!
    <pre><code class="cpp"></code></pre>
     
  2. rrrFer

    rrrFer Well-Known Member
    Команда форума C\C++ Team

    Регистрация:
    6 сен 2011
    Сообщения:
    1.324
    Симпатии:
    36
    Потому что strtok - это стандартная функция, которая поддерживается всеми компиляторами Си/С++.
    Поэтому описана она нормально и даже на страницах man про нее исчерпывающая информация.

    strtok_s - поделка майкрософта, которая работает только в одном компиляторе (от майкрософта), поэтому про нее написано только на msdn.
    Больше чем на сайте майкрософта (msdn), ссылку на который вы дали, информации не будет.
     
  3. abyss

    abyss Member

    Регистрация:
    5 сен 2013
    Сообщения:
    8
    Симпатии:
    0
    вот же блин, там не особо пока понятно что написано, не заострял внимание, хотел найти материал немного в другом описании.
    раз так ничего не поделаешь, придётся как то справиться.

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

    в любом случае спасибо за подробные разъяснения!!
     
  4. rrrFer

    rrrFer Well-Known Member
    Команда форума C\C++ Team

    Регистрация:
    6 сен 2011
    Сообщения:
    1.324
    Симпатии:
    36
    Потому, что ты используешь поделки майкрософта. А им выгодно пересадить юзеров к своим унылым функциям (их много, все заканчиваются на _s). Потом юзеры не смогут нормально работать под линуксом, например.

    Но а если серьезно, то да, функция не безопасна. И gcc тоже вроде бы о таких штуках сообщает.
    Если предупреждения не нравятся - можно залезть в настройки студии и отключить.

    Посмотри вот тут пример использования: http://www.cplusplus.com/reference/cstring/strtok/
    должно быть понятно, что это плохая, опасная функция. На поверхности лежит куча вариантов допустить ошибку.

    Допустим
    strtok(str, str + 99);
    // я в строке с 99 символа разместил разделители и пытаюсь выделить слова в остальной строке.
    понятно, что код бредовый 9примеры надуман и высосан из пальца), но сломается 99%, хотя...казалось бы..ничего незаконного нет.

    По ссылке выше есть предупреждение еще:
    Это хорошо? - я думаю нет, опасно.
    Ну а передача NULL в качестве аргумента - это вообще хак какой-то. Видимо внутри нее статическая переменная, поэтому она так себя ведет. Но это ужасно опасно.
    Код (Text):
     pch = strtok (str," ,.-");
    while (pch != NULL)
    {
    // а что если вот тут мне надо вызвать strtok для какой-то другой строки str2? - я вызову,
    //но цикл сломается, потому что статическая переменная изменится
    pch = strtok (NULL, " ,.-");
    }
     
  5. abyss

    abyss Member

    Регистрация:
    5 сен 2013
    Сообщения:
    8
    Симпатии:
    0
    Такого нет чтобы не нравилось, возникли вопросы из-за того, что компилятор сообщил предупреждение. Вот решил найти о чём это он начал писать. А оказалось ответ я самостоятельно мог бы и не найти, если бы вы в начале не написали объективно в чём дело. Верней возможно нашёл, после как набрался бы опыта возможно, только это было не скоро.

    не совсем понятно про статическую переменную, к чему она относится?, предположение - это про NULL? или ?...

    про этот цикл while (pch != NULL), да пример интересный, если туда поместить вызов другой функции если я понял правильно вашу мысль, но в каком таком случае это может понадобится, для меня это пока остаётся за гранью моего представления знаний вообще

    можно другой вопрос не относящийся к данной теме больше к указателям:
    Код (C++):
    char noun[] = "boy girl dog town car";
    char *i;

    i = strtok(noun, " ");

    for(int j = 0; j < 4; j++){

    cout << i << endl;
    i = strtok(NULL, " ");

    } cout << i << endl;
    вот код, вопрос в том как указатель отображает все символы в лексеме вместо одного, не совсем понятно, с целым числом там ещё можно это представить там одно значение, а здесь же не один символ и он их отображает. Понятно что он ссылается на массив, но он же не может помнить значения, а на экран выводит все токены... )
     
  6. rrrFer

    rrrFer Well-Known Member
    Команда форума C\C++ Team

    Регистрация:
    6 сен 2011
    Сообщения:
    1.324
    Симпатии:
    36
    статическая переменная - это переменная, перед объявлением которой стоит слово static.

    Код (Text):
    #include <iostream>

    int foo (int val) {
    static int t = val;

    return t++;
    }

    int main() {
    std::cout << "12: " << foo(12) << std::endl;
    std::cout << "1: " <<foo(1) << std::endl;
    std::cout << "0: " <<foo(0) << std::endl;
    std::cout << "6: " <<foo(6) <<std::endl;
    }
    вывод:
    Т.е. я инициализировал значение статической переменной 1 раз, а обращаюсь к ней потом, но уже не важно что я туда передаю, оно не сбрасывается (t++ просто увеличивает счетчик, чтобы было понятно что что-то работает).

    Вот примерно такая же лабуда сидит внутри strtok. Если я вместо аргумента передаю NULL - то значение не обновляется. Ну примерно актой код в начале этой функции:

    Код (Text):
    strtok(char *ptr) {
    static *sptr = 0;
    if (ptr != 0) sptr = ptr;
    // ...
    }
    Ну мне так кажется. А это плохо и внезапно.
     
  7. abyss

    abyss Member

    Регистрация:
    5 сен 2013
    Сообщения:
    8
    Симпатии:
    0
    - пример понятен, предпологал подобное в вопросе про NULL, только не так точно, да это прям зараза какая та ))

    в общем ничего хорошего нам это возможно не светит
    - с другой стороны, а как же ей переходить к следующим значениям если не будет подобной ситуации
    - раз эта функция такая и не расчитана на подобные конструкции, как в примере
    // а что если вот тут мне надо вызвать strtok для какой-то другой строки str2?
    значит так делать нельзя или искать варианты
     
  8. rrrFer

    rrrFer Well-Known Member
    Команда форума C\C++ Team

    Регистрация:
    6 сен 2011
    Сообщения:
    1.324
    Симпатии:
    36
    Ну скажем так. Код имеет свойство дописываться и изменяться.
    Я использовал функцию foo и strtok - все было окей. Но разработчик, который пилит foo взил и начал в ней тоже использовать strtok (ну понадобилось ему).
    Все сломалось, потому что статическая переменная... Ошибку искать разработчики будут долго, потом будут долго выяснять отношения по теме "кому strtok нужнее". Хуже статики ничего в этом мире нет. Даже сам дьявол кажется ангелом на ее фоне.
     
  9. abyss

    abyss Member

    Регистрация:
    5 сен 2013
    Сообщения:
    8
    Симпатии:
    0
    Да логические ошибки искать долго ...

    А что касаемо примера с указателем, как же он передаётт значения, сразу лексемы а не токена?
     
  10. abyss

    abyss Member

    Регистрация:
    5 сен 2013
    Сообщения:
    8
    Симпатии:
    0
    этот вопрос был выше в примере:

    Код (C++):
    char noun[] = "boy girl dog town car";
    char *i;

    i = strtok(noun, " ");

    for(int j = 0; j < 4; j++){

    cout << i << endl;
    i = strtok(NULL, " ");

    } cout << i << endl;
    вот код, вопрос в том как указатель отображает все символы в лексеме вместо одного, не совсем понятно, с целым числом там ещё можно это представить там одно значение, а здесь же не один символ и он их отображает. Понятно что он ссылается на массив, но он же не может помнить значения, а на экран выводит все токены... )
     
  11. rrrFer

    rrrFer Well-Known Member
    Команда форума C\C++ Team

    Регистрация:
    6 сен 2011
    Сообщения:
    1.324
    Симпатии:
    36
    указатель указывает на область памяти. В памяти хранится строка.
    Ты можешь поместить указатель на второй, десятый, любой символ. При выводе будет выведена вся строка.

    Строка в Си - это последовательность байт, завершающаяся нуль-терминатором. Т.е. не важно сколько там символов - будет выведена вся строка до тех пор пока не встретится нуль. так оно и работает. С чего вы решили что должен выводиться только 1 символ?

    Ну я как бэ догадывался что студенты вообще не представляют как выглядит память, я советовал им посмотреть книжки для дошкольников (у меня такие были, с рисунками всякими в стиле детских раскрасок) по программированию (в союзе такие выпускались). Ну и на доске мелом рисовал. Как вам нарисовать - не знаю. Мела нет.

    Добавлено: а че вам дался этот strtok? вы без него обойтись не можете?
     
  12. abyss

    abyss Member

    Регистрация:
    5 сен 2013
    Сообщения:
    8
    Симпатии:
    0
    Со своей стороны вижу, совершенно не правильно задал вопрос.
    Постараюсь немного по другому:
    -происходит вызов функции, на экран выводится слово.
    - так вот и не очень понятно почему происходит вывод слова, а не одного символа.

    а насчёт обойтись или нет, для меня это не принципиально, ну такой подход, надо же разобраться.

    если правильно понимаю, вывод всего слова происходит из-за функции, это как цикл, допустим while, там пока условие соблюдается он и происходит, "и ни дай Бог ты пролетишь в бесконечный цикл" ))
    вот меня и парило как же этот указатель такое делает, а оказывается он ссылается на каждый символ пока не встретит условие завершения, в нашем случае это пробел.

    на ваш взгляд мысль верна?
     
  13. rrrFer

    rrrFer Well-Known Member
    Команда форума C\C++ Team

    Регистрация:
    6 сен 2011
    Сообщения:
    1.324
    Симпатии:
    36
    abyss
    потому что strtok возвращает char* а не char.
    Первое - строка, второе - символ.

    на мой взгляд, в корне не верна.
     
  14. abyss

    abyss Member

    Регистрация:
    5 сен 2013
    Сообщения:
    8
    Симпатии:
    0
    В любом случае вы ответили на мой вопрос, который был в начале, спасибо.

    Всё остальное пока из-за нехватки каких то знаний или опыта. Наверно нужно дойти до этого самому.
    У вас хороший форум с нужными специалистами, побольше бы тех кто тянется к обучению, практике и др., а не тех кто ищет кто бы чтобы за них сделал и подобное хозяйство. И сами время в пустую тратят и замыливают правильный взгляд специалистов.

    Удивительно, что из трёхсот примерно просмотров ни один человек не вмешался в наш разговор, ничего не добавил...
     
  15. rrrFer

    rrrFer Well-Known Member
    Команда форума C\C++ Team

    Регистрация:
    6 сен 2011
    Сообщения:
    1.324
    Симпатии:
    36
    так-то тут, в основном Lotus-программисты.
    На С++ тут пишет 2-3 человека. И заходят они редко :(.

    Но обращайтесь, если что )
     
  16. Pingvin1

    Pingvin1 Well-Known Member

    Регистрация:
    20 июл 2009
    Сообщения:
    50
    Симпатии:
    0
    В strtok нет места статическим переменным. Функция не безопасна так как меняет входную строку: разделители на 0-символы и указывает на следующую лексему, так сделано в Dev 5. Обычно в С функция работает с копией входной переменной.
     
Загрузка...

Поделиться этой страницей