|
90 / 90 / 48
Регистрация: 07.12.2011
Сообщений: 215
|
|||||||||||||||||||||
Запись вектора строк в массив указателей на тип char15.12.2013, 15:29. Показов 5033. Ответов 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 Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip
На первой гифке отладочные линии отключены, а на второй включены:. . .
|
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&d=1772460536
Одним из. . .
|
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
|
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
|
|
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
|
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога
Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
|
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование
. \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json>
Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом.
# Check if. . .
|
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так:
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347
Основана на STM32F303RBT6.
На борту пять. . .
|