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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.69
Navern
4 / 4 / 0
Регистрация: 01.10.2011
Сообщений: 33
#1

Функция strtok. Представление телефонного номера в виде строки. - C++

27.10.2011, 20:05. Просмотров 1868. Ответов 20
Метки нет (Все метки)

Запутался в функции strtok. Причем уже сделал для неё пару упражнений, вроде понимаю как она работает. По крайней мере с предложением из слов. Задание звучит так, используя функцию strtok, разбить телефонный номер формата (555) 555-5555, введенный как строку, на лексемы. Где первой лексемой будет код, второй первые три цифры номера, а третьей после четыре цифры. Я смог выбить код, и перевести его в тип данных int. Но когда пытаюсь продолжать обработать строку, то вылазит ошибка выхода за границы массива.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
   char phoneNumber[40];
   char code[3];
   int codeRegion;
   char *codePtr = NULL;
   char *numberPtr = NULL;
 
   cout << "Enter the telephone number in format: (555) 555-5555:\n";
   cin >> phoneNumber;
    
   codePtr = strtok(phoneNumber, " ");
    
   for ( int i = 0; i < 3; i++)
      code[i] = codePtr[i+1];
  
   codeRegion = atoi(code);
    
   codePtr = strtok(NULL, " ");
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.10.2011, 20:05
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Функция strtok. Представление телефонного номера в виде строки. (C++):

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

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

Вернуть текстовое представление уравнения в виде строки - C++
последний пункт задания лабы: Вернуть текстовое представление уравнения в виде строки (char или wchar_t). уравнение такое ...

Представление в виде строки, где триады цифр отделены друг от друга пробелами - C++
Здравствуйте, задача такова: для заданного натурального числа n получить его правильное символьное представление в виде строки ...

Генератор слов для телефонного номера - C++
Вот такая вот интересная задачка у Дейтела есть: 17.13. (Генератор слов для телефонного номера) Стандартный набор кнопок телефона ...

Перечисления enum. Хранение типа телефонного номера - C++
Ввести в массив структур N записей из телефонной книжки (фамилия, имя, номер телефона, тип номер (домашний, рабочий, мобильный)). Вывести...

20
Сыроежка
Заблокирован
27.10.2011, 20:11 #2
Цитата Сообщение от Navern Посмотреть сообщение
Запутался в функции strtok. Причем уже сделал для неё пару упражнений, вроде понимаю как она работает. По крайней мере с предложением из слов. Задание звучит так, используя функцию strtok, разбить телефонный номер формата (555) 555-5555, введенный как строку, на лексемы. Где первой лексемой будет код, второй первые три цифры номера, а третьей после четыре цифры. Я смог выбить код, и перевести его в тип данных int. Но когда пытаюсь продолжать обработать строку, то вылазит ошибка выхода за границы массива.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
   char phoneNumber[40];
   char code[3];
   int codeRegion;
   char *codePtr = NULL;
   char *numberPtr = NULL;
 
   cout << "Enter the telephone number in format: (555) 555-5555:\n";
   cin >> phoneNumber;
    
   codePtr = strtok(phoneNumber, " ");
    
   for ( int i = 0; i < 3; i++)
      code[i] = codePtr[i+1];
  
   codeRegion = atoi(code);
    
   codePtr = strtok(NULL, " ");
Проблема в том, что вы портите ту строку, которую сканируете внутри strtok. То есть вам возвращается указатель из этой функции, который указывает на копию вашей строки phoneNumber, которая была сохранена в функции strtok.

Нет, не то я написал. У вас переменная code объявлена, как хранящая 3 символа. А для завершающего 0 места в ней нет. Поэтому когда вы выполняете

codeRegion = atoi(code);
то эта операция выходит за гринцу вашего массива code.

ОБъявите массив code по крайней мере как

C++
1
char code[4];
и после

C++
1
2
for ( int i = 0; i < 3; i++)
      code[i] = codePtr[i+1];
вставьте

C++
1
code[3] = '\0';
0
Navern
4 / 4 / 0
Регистрация: 01.10.2011
Сообщений: 33
27.10.2011, 20:17  [ТС] #3
Цитата Сообщение от Сыроежка Посмотреть сообщение
Проблема в том, что вы портите ту строку, которую сканируете внутри strtok. То есть вам возвращается указатель из этой функции, который указывает на копию вашей строки phoneNumber, которая была сохранена в функции strtok.
Я вроде как это понимаю(или как-то не так понимаю?)
Просто вот этот код для другого упражнения у меня работал

C++
1
2
3
4
5
6
7
8
9
    char *tokenPtr;
    
    tokenPtr = strtok(array1, " ");
    
    while (tokenPtr != NULL)
    {
       printLatinWord(tokenPtr);
        tokenPtr = strtok(NULL, " ");
    }
Добавлено через 4 минуты
Цитата Сообщение от Сыроежка Посмотреть сообщение
Проблема в том, что вы портите ту строку, которую сканируете внутри strtok
C++
1
2
3
4
   codePtr = strtok(phoneNumber, " ");
        
   for ( int i = 0; i < 3; i++)
      code[i] = codePtr[i+1];
в этом куске кода? Если да то всё понятно пойду исправлять.
0
Сыроежка
Заблокирован
27.10.2011, 20:17 #4
Цитата Сообщение от Navern Посмотреть сообщение
Я вроде как это понимаю(или как-то не так понимаю?)
Просто вот этот код для другого упражнения у меня работал

C++
1
2
3
4
5
6
7
8
9
    char *tokenPtr;
    
    tokenPtr = strtok(array1, " ");
    
    while (tokenPtr != NULL)
    {
       printLatinWord(tokenPtr);
        tokenPtr = strtok(NULL, " ");
    }
Добавлено через 4 минуты


C++
1
2
3
4
   codePtr = strtok(phoneNumber, " ");
        
   for ( int i = 0; i < 3; i++)
      code[i] = codePtr[i+1];
в этом куске кода? Если да то всё понятно пойду исправлять.
Я исправил свое первое сообщение. Перечитайте его.
1
Navern
4 / 4 / 0
Регистрация: 01.10.2011
Сообщений: 33
27.10.2011, 20:24  [ТС] #5
Цитата Сообщение от Сыроежка Посмотреть сообщение
Я исправил свое первое сообщение. Перечитайте его.
Всё спасибо, совершнно забыл о завершающем нулевом символе. Идиот

Добавлено через 3 минуты
Цитата Сообщение от Сыроежка Посмотреть сообщение
codeRegion = atoi(code);
то эта операция выходит за гринцу вашего массива code.
Кстати сейчас понял, что дело всё таки не в этом или не совсем в этом. Потому что когда я оставлял в упражнении только один экземпляр функции strtok, всё работало и код выводился в виде int значения. А когда добавлял второй экземпляр функции всё рушилось к чертям. Сейчас вроде исправил ошибку с нулём, но не помогло. Тут какая-то беда именно в том, что это цифры, или в том что есть скобки или в каком-то неправильном вызове strtok, только разобраться в этом не могу.
0
Сыроежка
Заблокирован
27.10.2011, 20:26 #6
Цитата Сообщение от Navern Посмотреть сообщение
Всё спасибо, совершнно забыл о завершающем нулевом символе. Идиот

Добавлено через 3 минуты

Кстати сейчас понял, что дело всё таки не в этом или не совсем в этом. Потому что когда я оставлял в упражнении только один экземпляр функции strtok, всё работало и код выводился в виде int значения. А когда добавлял второй экземпляр функции всё рушилось к чертям. Сейчас вроде исправил ошибку с нулём, но не помогло. Тут какая-то беда именно в том, что это цифры, или в том что есть скобки или в каком-то неправильном вызове strtok, только разобраться в этом не могу.
Вам надо проверять, не равно ли значение указателя,, возвращаемое функцией strtok, NULL.
0
Navern
4 / 4 / 0
Регистрация: 01.10.2011
Сообщений: 33
27.10.2011, 20:31  [ТС] #7
Цитата Сообщение от Сыроежка Посмотреть сообщение
Вам надо проверять, не равно ли значение указателя,, возвращаемое функцией strtok, NULL.
Да проверил, почему то при втором вызове указатель становится нулёвым. Только мне непонятно почему. У меня есть строка (555) 555-5555. Я из неё выделил в первый раз (555), это стопроцентов я проверил. Почему при втором вызове strtok, над той же строкой возвращается NULL указатель?
0
Olga_
842 / 184 / 16
Регистрация: 01.08.2011
Сообщений: 502
27.10.2011, 20:35 #8
Предлагаю разбивать строку на слова с помощью более хорошего метода, нежели strtok и очень быстрого:
http://www.cyberforum.ru/cpp-beginners/thread103665/post1880997.html
Функция strtok портит строку, а данный метод быстр и практичен)
0
Сыроежка
Заблокирован
27.10.2011, 20:41 #9
Цитата Сообщение от Navern Посмотреть сообщение
Да проверил, почему то при втором вызове указатель становится нулёвым. Только мне непонятно почему. У меня есть строка (555) 555-5555. Я из неё выделил в первый раз (555), это стопроцентов я проверил. Почему при втором вызове strtok, над той же строкой возвращается NULL указатель?
Это скорей всего из-за того, что следующего пробела функция не находит. Думаю, вам в качестве разделителя нужно включить символ конца строки '\n'.

Добавлено через 48 секунд
Цитата Сообщение от Olga_ Посмотреть сообщение
Предлагаю разбивать строку на слова с помощью более хорошего метода, нежели strtok и очень быстрого:
http://www.cyberforum.ru/showthread.php?p=1880997
Функция strtok портит строку, а данный метод быстр и практичен)
Лучше ножниц я другого метода не знаю!
0
Navern
4 / 4 / 0
Регистрация: 01.10.2011
Сообщений: 33
27.10.2011, 20:54  [ТС] #10
Цитата Сообщение от Olga_ Посмотреть сообщение
Предлагаю разбивать строку на слова с помощью более хорошего метода, нежели strtok и очень быстрого:
спасибо, но я пока обучаюсь и задание именно в использовании функции strtok. Так что не подойдет.



Цитата Сообщение от Сыроежка Посмотреть сообщение
Это скорей всего из-за того, что следующего пробела функция не находит. Думаю, вам в качестве разделителя нужно включить символ конца строки '\n'.
Сейчас попробую с этим. Парадокс в том, что когда я ставил разделителем символ '-' эффект был тот же. Плюс одни пробелы работали нормально, когда дело было со словами в предложении. В чем тут отличие не пойму.

Добавлено через 6 минут
Вообщем я не очень понял, но если вводить телефон в формате (555)555-5555, а не в формате, когда после кода (555) ставится пробел, то не выдает той же ошибки.
0
Olga_
842 / 184 / 16
Регистрация: 01.08.2011
Сообщений: 502
27.10.2011, 21:11 #11
Цитата Сообщение от Сыроежка Посмотреть сообщение
Лучше ножниц я другого метода не знаю!
Там правда ОЧЕНЬ хороший метод. А можете хоть немного поподробнее про метод ножниц?
0
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
27.10.2011, 21:24 #12
Цитата Сообщение от Olga_ Посмотреть сообщение
А можете хоть немного поподробнее про метод ножниц?
strtok и есть метод ножниц
0
Navern
4 / 4 / 0
Регистрация: 01.10.2011
Сообщений: 33
27.10.2011, 21:38  [ТС] #13
Вообщем как итог всё заработало, когда я стал вбивать код вместе с остальным телефонным номером без пробелов. Как это пофиксить так и не понял.
0
Olga_
842 / 184 / 16
Регистрация: 01.08.2011
Сообщений: 502
27.10.2011, 21:41 #14
Цитата Сообщение от Jupiter Посмотреть сообщение
strtok и есть метод ножниц
Но это не очень хорошая функция, можно сделать лучше и в то же время быстро. Тем более таким же методом (ножниц) можно написать функцию быстрее чем strtok (не намного, но все же)
0
Thinker
Эксперт С++
4228 / 2202 / 150
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
27.10.2011, 22:00 #15
Цитата Сообщение от Olga_ Посмотреть сообщение
Но это не очень хорошая функция

Не по теме:

Поддерживаю, сам задумывался над этим вопросом и редко использую strtok



Добавлено через 5 минут
При этом это можно сделать быстрее, поменяв такой код
C
1
2
3
len = strlen(DELIMITERS);
for (i = 0; i < len; i++)
     flag[DELIMITERS[i]] = 1;
на такой
C
1
2
for (i = 0; DELIMITERS[i]; i++)
     flag[DELIMITERS[i]] = 1;
то есть минус один проход по строке DELIMITERS
0
27.10.2011, 22:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.10.2011, 22:00
Привет! Вот еще темы с ответами:

Функция strtok() - C++
Доброе время суток! Подскажите пожалуйста в чем проблема и как с ней бороться. Имеем такой код: #include &lt;iostream&gt; ...

функция strtok() - C++
Объясните, пожалуйста, функцию strtok()...то что непонятно - заккоментила ps=strtok(str, &quot; &quot;); // понятно, что strtok () разбивает...

функция strtok - C++
расскажите алгоритм char str =&quot;- This, a sample string.&quot;; char * pch; printf (&quot;Splitting string \&quot;%s\&quot; into tokens:\n&quot;,str); ...

Автоматическое изменение префикса телефонного номера в зависимости от страны. Класс Person. - C++
Есть класс Person. Так же пару функций. Одно из заданий не работает: Если номер телефона начинается с 0 и страна «Украина» добавить...


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

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

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