|
90 / 90 / 48
Регистрация: 07.12.2011
Сообщений: 215
|
|||||||||||||||||||||
Запись вектора строк в массив указателей на тип char15.12.2013, 15:29. Показов 4997. Ответов 19
Метки нет (Все метки)
Решаю задачу 4.34 из книги Липпмана С. Язык программирования С++. Вводный курс. 4-е изд.
Задание: 1) Напишите программу, читающую строки в вектор. 2) Скопируйте этот вектор в массив указателей на тип char. Вообще там 4 задания, но у меня проблемы уже со 2м. Да, задача довольно известная, и даже на этом форуме есть тема, в которой предложено решение. Но я поставил себе 2 дополнительных условия. 1. Не использовать многомерные массивы (так как это только следующая тема в книге); 2. Не использовать индексацию на векторы и массивы, а использовать только итераторы и указатели. Вот код функции main.
qqq www eee Ожидаемый результат: qqq www eee qqq www eee Получаемый результат: qqq www eee eee eee eee Более того при отсутствии циклов для проверки я сделал так. Перед выводом на экран содержимого массива указателей:
Подскажите пожалуйста, где я ошибся. Добавлено через 1 час 18 минут Ошибку нашел. Объясните, пожалуйста, почему именно так. Если заменить итератор на индекс все работает. Но хотелось бы разобраться с итераторами. Т.б. если вместо
то все работает. Где я совершил ошибку при переделывании блока for под работу с итераторами? А так же вместо -
0
|
|||||||||||||||||||||
| 15.12.2013, 15:29 | |
|
Ответы с готовыми решениями:
19
Вектор строк и массив указателей на тип char Напишите программу, присваивающую значения элементов списка указателей на символьные строки в стиле С (тип char* ) элементам вектора строк
|
|
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
|
||||||
| 15.12.2013, 15:49 | ||||||
потом берется c_str и раздается всем. если размер s_temp не изменяется, то указатель, возвращаемый c_str - тоже не меняется. ну и получается что всем раздается один и тот же указатель. зачем копировать в s_temp? можно ведь сразу *p_to_arr = str_it->c_str();
2
|
||||||
|
Комп_Оратор)
|
||||||
| 15.12.2013, 15:57 | ||||||
|
Wlk, указывать внутрь вектора это плохо. Когда говорят, что вектор это массив имеют ввиду много общих черт, но только не постоянство размещения в памяти. Достаточно создать массив указателей на char:
и пробежавшись по вектору повыделять память и скопировать в нее поэлементно и поустанавливать переменные массива на полученные строки char *.
1
|
||||||
|
90 / 90 / 48
Регистрация: 07.12.2011
Сообщений: 215
|
||||
| 15.12.2013, 16:22 [ТС] | ||||
|
*p_to_arr = str_it->c_str(); - вот это решило проблему. Неувязка в том, что по ходу изучения книги этот оператор еще не встречался.
s_temp.c_str() - всегда указывает на одну и ту же область памяти, даже при том что данные хранимые в этой области могут меняться. В моем представлении s_temp.c_str() при каждом новом изменении данных хранимых в s_temp должно генерировать указатель на другую область в памяти. Видимо это не так. Или я не прав? Спасибо.
0
|
||||
|
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
|
|
| 15.12.2013, 16:39 | |
|
если размер буфера в строке не увеличивается (т.е. когда строка изменяется, но она умещается во внутренний буфер std::string), то перевыделять память нет особой нужды. она это и не делает. что в стандарте на этот счет написано - я не знаю. может там и нет гарантии, что это всегда так и закладываться на такую особенность не стоит. так же не стоит закладываться на то, что после изменения строки c_str вернет указатель на другой участок памяти.
1
|
|
|
Комп_Оратор)
|
||
| 15.12.2013, 17:04 | ||
|
DU, как я понимаю, для небольших или наперёд заданных векторов, это так и есть. Но если вектор не умещается в непрерывной области (перестал помещаться), то память может быть полностью перевыделена. Впрочем, это может быть реализовано по-разному.
0
|
||
|
90 / 90 / 48
Регистрация: 07.12.2011
Сообщений: 215
|
||||||||||||
| 15.12.2013, 17:21 [ТС] | ||||||||||||
|
Я это реализовал вот так:
И еще вопрос: почему при использовании
0
|
||||||||||||
|
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
|
|
| 15.12.2013, 17:39 | |
|
если указатель на константу - то он может сперва указывать на одну константу. потом на другу. это менять можно. это у вас и происходит. но вот значение этой константы через этот указатель поменять нельзя.
немного по проще (рассмотрим просто указатели, а не указатели на указатели). есть четыре разных варианта: 1) int* ptr; // неконстантный указатель на неконстантую область памяти. менять можно все. 2) const int* cptr; // указатель на константу. можно указывать на разные константы, но значения этих констант менять через этот указатель нельзя (они же константы). 3) int* const ptrc; // указывает на одну и ту же область памяти. на другую указать нельзя. но значение этой области менять можно. т.е. этот указатель указывает на неконстанту. 4) const int* const cptrc = 0; // указывает на одну и ту же область памяти. на другую указать нельзя. и значение этой области через этот указатель менять нельзя. т.к. он указывает на константу. добавте сюда еще указатели на указатели со всеми возможными вариантами константности и получится еще больше комбинаций
1
|
|
|
Комп_Оратор)
|
|||
| 15.12.2013, 17:48 | |||
|
ps мне нравится Липман. Если не обращать внимание на багатство примеров, этого везде достаточно. Но задачи у него вполне приличные. Обратите внимание на 2) задания: <<2) Скопируйте этот вектор в массив указателей на тип char. >> Ехидство состоит в том, что говорится чаще всего так, а имеется в виду: по указателю. И тут дело даже не в том, что указателю все равно на что он указывает. Кроме типа. Хотя и в этом тоже. Главное привыкнуть, что указатель хранит адрес, а значение лежит по этому адресу.
1
|
|||
|
90 / 90 / 48
Регистрация: 07.12.2011
Сообщений: 215
|
||
| 15.12.2013, 17:49 [ТС] | ||
|
0
|
||
|
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
|
||
| 15.12.2013, 18:02 | ||
|
есть еще трудности с терминами.
встречаются следующие варианты: константный указатель - тут не совсем понятно о чем это указатель на константу - тут все ок. зная это, предыдущий термин можно однозначно понимать так: константный указатель - этот то, который всегда указывает в одну и ту же область памяти. указать на другую запрещают правила с++ (константы инициализируются и больше не меняются).
0
|
||
|
90 / 90 / 48
Регистрация: 07.12.2011
Сообщений: 215
|
|
| 15.12.2013, 18:13 [ТС] | |
|
Да, во всех случаях имел ввиду указатель на константу (т.е. указатель без привязки к области памяти но без доступа на запись объекта на который он указывает).
Т.б. если V -переменная, const int *Р=&V - указатель на переменную с доступом на считывание (указатель на константу), То что такое const int **PP=&P - указатель на указатель на переменную с доступом на считывание (указатель на константу)? На что распространяется его ограничение доступа к записи? Только на конечную переменную V или и на адрес который в Р?
0
|
|
|
Комп_Оратор)
|
||||||
| 15.12.2013, 18:44 | ||||||
0
|
||||||
|
90 / 90 / 48
Регистрация: 07.12.2011
Сообщений: 215
|
|
| 15.12.2013, 18:48 [ТС] | |
|
Очень даже хорошо. Но. Вы конечно, с формальной точки зрения обошли индексы, и пользовались только итераторами и указателями. Но фактически shift_in_output_c_str=0 - это индекс элемента массива.
Эквивалетно *output_c_str[shift_in_output_c_st]. Мне тоже намного легче с индексами работать. Но тогда мне никогда не понять указателей ![]() У меня же использован указатель именно на текущий элемент массива, который рассматривается, и зная его не угадаешь, какой (какой по счету, с каким индексом) элемент массива под ним скрывается. Я даже не знаю хорошо это или плохо.
0
|
|
|
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
|
||||||
| 15.12.2013, 18:52 | ||||||
|
const int **PP=&P - это неконстантный указатель на неконстантный указатель на const int.
с тайпдефами чуть легче это все воспринимается. вот надеюсь ничего не напутал. используем тайпдефы + перегрузку и позволяем компилятору решить, что есть что и выдать нам результат:
1
|
||||||
|
Комп_Оратор)
|
||
| 15.12.2013, 19:11 | ||
![]() Создайте семь указателей типа char *one, char *two... и сами поймёте, что показывать такое никому не нужно.
0
|
||
|
90 / 90 / 48
Регистрация: 07.12.2011
Сообщений: 215
|
||||||
| 15.12.2013, 19:28 [ТС] | ||||||
Я вроде понял (или мне так только кажется), но уже при очеееень медленном восприятия этого всего. А файлик сразу сохранил. Хорошая шпаргалка мне будет.
0
|
||||||
|
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
|
|
| 15.12.2013, 20:09 | |
|
строка раскоменчена. это компилится. т.е. там все ок. должно быть так:
*(*pc) = 0; // ок. (*pc) - указывает на неконстанту. значит менять можно. наглючил при копипасте.
0
|
|
|
90 / 90 / 48
Регистрация: 07.12.2011
Сообщений: 215
|
|||||||
| 15.12.2013, 20:25 [ТС] | |||||||
|
Оно компилится да. Я имел ввиду так же что, если
Ну насчет 79 строки вы пояснили.
0
|
|||||||
|
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
|
||||||
| 15.12.2013, 20:40 | ||||||
|
да, верно подмечено. там тоже камент кривой. меняем на:
1
|
||||||
| 15.12.2013, 20:40 | |
|
Помогаю со студенческими работами здесь
20
Ввод строк и запись их в массив указателей Создать специфицированный шаблон функции, принимающей массив указателей на char и количество самих указателей Массив указателей на массив строк и сортировка массива указателей Как удалить массив указателей char* Запись строки char в массив char Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение.
И на уровне агентов добавится между грибами или бактериями взаимодействий.
До того я пробовал подход через многомерные массивы,. . .
|
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Сочетание глобально распределённой вычислительной мощности и инновационных. . .
|
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Налог на собак: https:/ / **********/ gallery/ V06K53e
Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf
Пост отсюда. . .
|
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop?
Ниже её машинный перевод.
После долгих разбирательств я наконец-то вернула себе. . .
|
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод
Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод.
Thinkpad X220 Tablet —. . .
|
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|