Форум программистов, компьютерный форум CyberForum.ru

strtok - C++

Восстановить пароль Регистрация
 
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
01.12.2012, 07:23     strtok #1
Привет!
Решаю задачку на строки char. Возникла проблема вот код:
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//vuravnivanie slov po levomy i pravomy pol9m stranicu
 
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
 
#include <cstring>
using std::strlen;//return kolichestvo simvolov do zavershayuchego simvola
using std::strcat;//konkatenaci9 tipov char
using std::strtok;//razbivaet stroky na leksemu
using std::strcmp;//sravnivaet dve stroki
 
int main()
{
    char s[300]="1 to be, or not to be: that is\n2. the question: Whether 'tis nobler\n3. in the mind to suffer";
    char *leksema;
    int dob_sim[100]={0};
    char *str[100];
    for(int i=0;i<100;i++)
        str[i]=NULL;
    
    int b=0;
    leksema=strtok(s,"\n");
    while(leksema!=NULL)
    {   
        int count=0;
        for(int i=0;leksema[i]!='\0';i++)
        {
            count++;
        }
        dob_sim[b]=65-count;
        str[b]=leksema;
        b++;
        leksema=strtok(NULL,"\n");
    }
    for(int i=0;i<3;i++)
    {
        cout <<"str["<<i<<"]= "<<str[i]<<endl;
        cout <<"dob_sim["<<i<<"]= "<<dob_sim[i]<<endl;
    }
    
    char *str1[100];
    for(int i=0;i<100;i++)
        *(str1+i)=*(str+i);
    
    for(int i=0;i<3;i++)
    {
        cout <<"str1["<<i<<"]= "<<str1[i]<<endl;
        cout <<"str["<<i<<"]= "<<str[i]<<endl;
    }
    cout <<"&str[0]= "<<&str[0]<<" &str1[0]= "<<&str1[0]<<endl;
    cout <<"*str= "<<*str<<" *str1= "<<*str1<<endl;
    for(int i=0;i<3;i++)
    {
        leksema=strtok(str1[i]," ");
        while(leksema!=NULL)    
        {
            cout <<"leksema= "<<leksema<<endl;
            leksema=strtok(NULL," ");
        }
        
    }
    
    for(int i=0;i<3;i++)
    {
        cout <<"str1["<<i<<"]= "<<str1[i]<<endl;
        cout <<"str["<<i<<"]= "<<str[i]<<endl;
    }
    
    
    
 
    
    
    
    return 0;
}
код работает без ошибок но почему то неправильно.
есть 2 переменные char *str[100] и char *str1[100];
в них содержатся одинаковые данные;
выводятся как положено;
после того как я прогоняю функцию strtok;
leksema= strtok(str1[i]," ");
у меня чото и в str меняются значения?; спрашивается почему?;
ведь char *str1[100] и *char * str[100]; это указатели на разные адреса памяти;
в них хранятся абсолютно разные значения;
при изменении str1 допустим str1[0]="kkk" значение в str[0] не меняется проверял.
Но при использовании функции strtok(str1[0]," ") почему то меняется и str[0];
В чем проблема не могу никак разобраться хелп!!!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.12.2012, 07:23     strtok
Посмотрите здесь:

strtok C++
strtok C++
C++ warning strtok
C++ strtok
C++ Двойной strtok
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11823 / 6802 / 769
Регистрация: 27.09.2012
Сообщений: 16,870
Записей в блоге: 2
Завершенные тесты: 1
01.12.2012, 08:28     strtok #2
Функция strtok изменяет исходную строку. Поэтому, если строка Вам еще нужна, то передавайте в функцию копию строки
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
01.12.2012, 08:35  [ТС]     strtok #3
Так я ж и создал копию строки str1[100]
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11823 / 6802 / 769
Регистрация: 27.09.2012
Сообщений: 16,870
Записей в блоге: 2
Завершенные тесты: 1
01.12.2012, 11:29     strtok #4
Цитата Сообщение от ninja2 Посмотреть сообщение
Так я ж и создал копию строки str1[100]
Ткните носом меня в то место, где Вы создаете копию строки?
C++
1
char *str1[100];
Это массив указателей
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
01.12.2012, 12:18  [ТС]     strtok #5
строка 44 я объявляю новый массив str1[100] и дальше инициализирую его значениями массива str[100];
C++
1
2
3
char *str1[100];
    for(int i=0;i<100;i++)
        *(str1+i)=*(str+i);
я еще перепроверял массив ли это указателей :
C++
1
2
3
4
5
for(int i=0;i<3;i++)
    {
        cout <<"str1["<<i<<"]= "<<str1[i]<<endl;
        cout <<"str["<<i<<"]= "<<str[i]<<endl;
    }
проверил адреса если б это были 2массива на одни и те же значения то наверно у них бы были адреса однинаковые:
C++
1
2
cout <<"&str[0]= "<<&str[0]<<" &str1[0]= "<<&str1[0]<<endl;
    cout <<"*str= "<<*str<<" *str1= "<<*str1<<endl;
выводит что адреса разные а значение одинаковые; значит это два разных массива?
еще проверял изменял елемента одного из массивов и выводил значение другого
допустим так:
C++
1
2
str1[1]="kdjflasdjflkasdjlfjasdlf";
cout <<"str[1]= "<<str[1]<<" str1[1]= "<<str[1]<<endl;
выводится два разных значения;
все правильно ведь два разных массива казалось бы?;
но когда используеш strtok то меняются оба
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for(int i=0;i<3;i++)
    {
        leksema=strtok(str1[i]," ");
        while(leksema!=NULL)    
        {
            cout <<"leksema= "<<leksema<<endl;
            leksema=strtok(NULL," ");
        }
        
    }
    
    for(int i=0;i<3;i++)
    {
        cout <<"str1["<<i<<"]= "<<str1[i]<<endl;
        cout <<"str["<<i<<"]= "<<str[i]<<endl;
    }
в strtok str1 передаю; меняется и str;
во загадка?: если просто изменить значение какого нибудь элемента массива то значение во втором массиве не меняется; а если через функцию то сразу и во втором массиве значения меняется ???
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11823 / 6802 / 769
Регистрация: 27.09.2012
Сообщений: 16,870
Записей в блоге: 2
Завершенные тесты: 1
01.12.2012, 16:16     strtok #6
Никакой загадки тут нет. Еще раз прочитайте о работе функии strtok. Если все же будет не понятно, я вечером напишу что к чему, ибо сейчас я пишу с телефона, что не очень то и удобно
NickHammer
0 / 0 / 0
Регистрация: 05.09.2013
Сообщений: 2
05.09.2013, 02:04     strtok #7
Доброй ночи
Не нашел в теме ответа на вопрос. Пытаюсь написать простейшую лабу - отыскать в строке самое длинное и самое короткое слова, и указать их. Сочинил вот это :
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
#include <iostream>
#include <string.h>
 
using namespace std;
int main()
{
char str[256]; 
char *pch;
char *sMax;
char *sMin;
int nMax, nMin; //количество символов в максимальном и минимальном слове
cout << "Input string: " << endl;
cin.getline (str, 255);
nMax=0; nMin=0;
pch = strtok(str, ",!? ");
nMax=strlen(pch);
nMin=strlen(pch);
if (pch!=NULL)
{
    cout << pch << endl;
    while (pch=strtok(NULL, ",!? ")) 
        {
            cout << pch << endl; 
 
            if (strlen(pch)>nMax) 
                {
                    nMax=strlen(pch);
                    sMax = pch;
                }
            else if (strlen(pch)<nMin)
                {
                    nMin=strlen(pch);
                    sMin = pch;
                }
        
        }
 
}
cout << nMax << endl;
cout << nMin << endl;
cout << sMax << endl;
cout << sMin << endl;
 
system("pause");
return 0;
}
Это компилируется. И отрабатывает. Отрабатывает корректно. Но только 1 раз! При втором запуске (и последующих) - Нарушение прав доступа при чтении. Если убрать последние 2 cout - там где вывод самих слов - проблем нет. Как же такое возможно? Help please!
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11823 / 6802 / 769
Регистрация: 27.09.2012
Сообщений: 16,870
Записей в блоге: 2
Завершенные тесты: 1
05.09.2013, 05:32     strtok #8
Исправлял "на коленке", так что...
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
#include <iostream>
#include <cstring>
 
using namespace std;
 
int main() {
  char str[256] = { 0 } ; 
  char *pch = NULL ;
  char *sMax = NULL ;
  char *sMin = NULL ;
  int nMax = 0 , nMin = 0 ; //количество символов в максимальном и минимальном слове
  cout << "Input string: " << endl;
  cin.getline (str, 255);
  if ( ( nMin = strlen ( str ) ) == 0 ) {
    std::cerr << "Error" << std::endl ;
    return 1 ;
  }
  sMax = sMin = pch = strtok(str, ",!? ");
 
  while ( pch != NULL ) {
    cout << pch << endl;
    int tempStringSize =  strlen(pch) ;
    if ( tempStringSize > nMax ) {
      nMax=tempStringSize;
      sMax = pch;
      pch = strtok(NULL, ",!? ") ; 
      continue ;
    }
    if ( tempStringSize < nMin ) {
      nMin=tempStringSize;
      sMin = pch;
    }
    pch = strtok(NULL, ",!? ") ; 
  }
  
  cout << nMax << endl;
  cout << nMin << endl;
  cout << sMax << endl;
  cout << sMin << endl;
  return 0;
}
dmitry94
517 / 187 / 34
Регистрация: 25.05.2012
Сообщений: 780
05.09.2013, 05:47     strtok #9
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
#include <iostream>
using namespace std;
 
int main()
{
#define size 256
    char str[size];
    char sMax[size];
    char sMin[size];
    int nMax = 0;
    int nMin = size;
    sMin[0] = 0;
 
    char *pch;
 
    cout << "Input string: " << endl;
    cin.getline (str, 255);
 
    int l=strlen(str);
 
    if (l < 1 || l > size-1) return -1;
 
    pch = strtok(str,",!? ");
 
    while (pch!=NULL)
    {
        cout << pch << endl; 
 
        l = strlen(pch);
        if (l > nMax) 
        {
            nMax = l;
            strcpy(sMax,pch);
            if (!*sMin) strcpy(sMin,sMax);
        }
        else if (l < nMin)
        {
            nMin = l;
            strcpy(sMin,pch);
        }
        
        pch = strtok(NULL,",!? ");
    }
    cout << "max=" << sMax << " len=" << nMax << endl;
    cout << "min=" << sMin << " len=" << nMin << endl;
    return 0;
}
Добавлено через 48 секунд
Опаздал..
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.09.2013, 15:48     strtok
Еще ссылки по теме:

Функция strtok() C++
C++ Strtok противоположность
Использование STRTOK Разбить строку на слова, из слов составить список C++ Функция strtok C++

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

Или воспользуйтесь поиском по форуму:
NickHammer
0 / 0 / 0
Регистрация: 05.09.2013
Сообщений: 2
05.09.2013, 15:48     strtok #10
Спасибо! Работает как нельзя лучше. В любом случае, странно, что на 1 раз получалось отработать, а последующие нет... Получается, pch не обнулялось? После сообщения об ошибке появлялось окно strlen.asm. Я правильно понимаю, ошибка была в использовании if {а здесь весь цикл} ?
Yandex
Объявления
05.09.2013, 15:48     strtok
Ответ Создать тему
Опции темы

Текущее время: 09:14. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru