|
90 / 90 / 48
Регистрация: 07.12.2011
Сообщений: 215
|
|||||||||||||||||||||
Запись вектора строк в массив указателей на тип char15.12.2013, 15:29. Показов 5003. Ответов 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 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
|
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11
— это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
|
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11
Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
|
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
|
|
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/
O1rJuneU_ls
https:/ / vkvideo. ru/ video-115721503_456239114
|
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ВВЕДЕНИЕ
Введу сокращения:
аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
|
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi
ветка по-частям.
коммит Create переделка под биомассу. txt
вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
|
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ *
Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во
всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
|