Форум программистов, компьютерный форум, киберфорум
Наши страницы

C для начинающих

Войти
Регистрация
Восстановить пароль
 
Belkin Slava
0 / 0 / 0
Регистрация: 31.03.2012
Сообщений: 13
#1

strtok - изменение данных при использовании - C (СИ)

16.12.2012, 01:03. Просмотров 462. Ответов 8
Метки нет (Все метки)

Здравствуйте!

При написании программы столкнулся со следующей проблеммой...
Вот код (все лишнее из своей программы вырезал - чтобы показать ошибку):

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main ()
{
  char *str ="This a sample string";
  char *pch;
  char *rt=str;
  
  pch = strtok (str," ");
  printf ("%s\n",str);
  
  printf ("%s\n",rt);
  
  return 0;
}
Когда использую функцию strtok, то происходит магическое изменение содержимое переменной rt
Тоесть после токо как str разбивается по пробелам, то содержимое rt будет "This"
Вот тут я вступоре совсем, это как такое возможно
Отдельный указатель вроде на переменную, ну окей ей присваиваю содержимое str, причем естественно если str изменю (после того, как rt=str) - то содержимое rt никак не изменится.
Но Как токо использую strtok - все...
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.12.2012, 01:03
Здравствуйте! Я подобрал для вас темы с ответами на вопрос strtok - изменение данных при использовании (C (СИ)):

Исправить ошибку при использовании strtok - C (СИ)
Здравствуйте! Подскажите, пожалуйста, почему в строчке № 6 - &quot;char *s = strtok...&quot; программа выдаёт ошибку. Если меняю пробел на...

Strtok для двумерного массива строк: При первом же заходе в цикл, функция возвращает NULL - C (СИ)
Суть вот в чем: нужно ввести массив строк, затем в каждой строчке выделить 5-ое слово (в каждой строчке всего 5 слов), и перевести в число...

Ошибка при при использовании realloc - C (СИ)
В методе AddItem вылетает ошибка доступа к памяти... С чем это может быть связано? #pragma hdrstop #pragma argsused #include...

Ошибка при использовании Clrscr - C (СИ)
#include &lt;stdio.h&gt; #include &lt;math.h&gt; #include&lt;iostream&gt; double SumD(int a) { double s=a; int i=0; while...

Ошибка при использовании delete - C (СИ)
#include &lt;iostream&gt; #include &lt;stdio.h&gt; using namespace std; void main() { char *ar=new char ; ar=&quot;12345qwer&quot;; ...

Ошибка при использовании strlen - C (СИ)
scanf(&quot;%s&quot;,&amp;s); d=strlen(s); чего ошибка?

8
fasked
Эксперт С++
4948 / 2528 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
16.12.2012, 10:03 #2
Belkin Slava, так а в чем собственно проблема?
0
Байт
Диссидент
Эксперт C
16574 / 10844 / 1652
Регистрация: 24.12.2010
Сообщений: 20,974
16.12.2012, 13:01 #3
Указатель rt не меняется, он как указывал на область памяти где содержалось "This a sample string", так и указывает. Функция strtok вместо первого пробела ставит 0.
Как ты меняешь str ? Если так str = "New string", то str стал уже указывать на другую область памяти
1
Belkin Slava
0 / 0 / 0
Регистрация: 31.03.2012
Сообщений: 13
16.12.2012, 13:23  [ТС] #4
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  char *str ="This a sample string";
  char *pch;
  char *rt=str;
  
  printf ("%s\n",rt);
  //     "This a sample string";
 
  pch = strtok (str," ");
  
  printf ("%s\n",rt);
  //     "This";
  
  return 0;
}
Желалось бы чтобы после использования strtok rt не изменялось)
0
fasked
Эксперт С++
4948 / 2528 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
16.12.2012, 14:02 #5
Цитата Сообщение от Belkin Slava Посмотреть сообщение
Желалось бы чтобы после использования strtok rt не изменялось)
Ну так скопируй всю строку в новый массив перед использованием strtok.
1
Байт
Диссидент
Эксперт C
16574 / 10844 / 1652
Регистрация: 24.12.2010
Сообщений: 20,974
16.12.2012, 14:13 #6
Цитата Сообщение от Belkin Slava Посмотреть сообщение
Желалось бы чтобы после использования strtok rt не изменялось)
Или придумай другую функцию
Ты хорошо понимаешь, что такое указатель?
1
Belkin Slava
0 / 0 / 0
Регистрация: 31.03.2012
Сообщений: 13
16.12.2012, 14:27  [ТС] #7
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main ()
{
  char str[] ="This a sample string";
  char *pch;
  char  rt[1024];
  
  strcpy(rt,str);
  
    printf ("%s\n",rt);
  pch = strtok (str," ");
  
  printf ("%s\n",rt);
  
  return 0;
}
Спасибо большое, конечно ж я копировал и до этого, только забывал при объявление хразмерность указывать...
0
easybudda
Модератор
Эксперт CЭксперт С++
9695 / 5645 / 963
Регистрация: 25.07.2009
Сообщений: 10,850
16.12.2012, 14:48 #8
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Байт Посмотреть сообщение
Ты хорошо понимаешь, что такое указатель?
Кстати про указатели... После объявления
Цитата Сообщение от Belkin Slava Посмотреть сообщение
char *str ="This a sample string";
вызов strtok
Цитата Сообщение от Belkin Slava Посмотреть сообщение
pch = strtok (str," ");
должен бы приводить к ошибке времени выполнения. И старый gcc именно так код и компилировал:
Bash
1
2
3
4
5
6
bash-3.2$ gcc -o belkin_strtok belkin_strtok.c
bash-3.2$ ./belkin_strtok
Bus error
bash-3.2$ gcc -dumpversion
4.0.1
bash-3.2$
str указывает на строковый литерал, который должен бы находиться в памяти "только для чтения". По какой причине не валится код, скомпилированный в последних версиях gcc, я не знаю, но что тогда должно происходить при таком подходе:
C
1
2
char * s = "Hello";
strcat(s, " world");
Таки скомпилируется и как-то отработает?

Впрочем в случае со strtok достаточно изменить объявление
C
1
char str[] = "This a sample string";
при этом после вызова strtok(str, " ") строка изменится на "This\0a\0sample\0string\0"; (в конце строки \0 ставится неявно при объявлении).
3
Байт
Диссидент
Эксперт C
16574 / 10844 / 1652
Регистрация: 24.12.2010
Сообщений: 20,974
16.12.2012, 17:37 #9
Цитата Сообщение от easybudda Посмотреть сообщение
str указывает на строковый литерал, который должен бы находиться в памяти "только для чтения". По какой причине не валится код, скомпилированный в последних версиях gcc,
Угу! На этом деле я как-то здорово попался. Трое суток понять не мог. На моем компе транслируя под Борландом все отлично работало (я там аккуратненько один символ заменял, а затем восстанавливал. Причем все это происходило упрятанное в функцию, а то что мне ругалось, мол подставляешь const char* вместо char *, так я лихо игнорнул, сделав явное приведение) А когда скомпилировал на хосте (gcc, Linux) - все валилось. Т.е. там все действительно помещалось в память "read only". Но все-таки на одну дурость стал умнее
1
16.12.2012, 17:37
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.12.2012, 17:37
Привет! Вот еще темы с ответами:

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

Вылет при использовании динамической памяти - C (СИ)
Доброго времени суток, у меня возникла проблема с одной задачей: Дана матрица mx, числа &quot;а&quot; и &quot;ь&quot; - любые целые числа. Вывести матрицу на...

Ошибка при использовании пользовательской библиотеки - C (СИ)
Уважаемые программисты, помогите найти причину ошибки! float a,b,c; int i,n,j; #include&lt;stdio.h&gt; #include&lt;conio.h&gt; ...

Ошибка при использовании аргумента по умолчанию - C (СИ)
Не пойму, почему ошибка? #include &lt;stdio.h&gt; int arav(int amount=5) { return ++amount; } int main()


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

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

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