![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Vendigo |
|
||||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
Чем спамить в разных темах решил создать свою, где и буду озвучивать все те вопросы которые возникают у меня при изучении этого языка.
Добавлено @ 18:34 Для начала сугубо конкретный вопрос. Помогите найти ошибку. У меня есть структура:
И функция которая вводит данные в структуру:
Функция gets() работает неправильно, срабатывает только второй вызов этой функции. Если использовать оператор cin >> то все работает нормально. Насколько я понимаю в функцию gets() в качестве параметра нужно передать имя символьного массива (эдакую строку) без индекса. Имя символьного массива без индекса в свою очередь трактуется в С++ как указатель на его первый [0] элемент. Разве член структуры Data_book[i].name не соответствует этому определению? |
||||
|
|||||
Partizan |
|
|||
![]() Let's do some .NET ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2828 Регистрация: 19.12.2005 Где: Санкт-Петербург Репутация: 4 Всего: 67 |
Во первых какую размерность имеет Data_book???
упс ![]() Это сообщение отредактировал(а) Partizan - 13.1.2006, 18:50 -------------------- СУВ, Partizan. |
|||
|
||||
_hunter |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 8564 Регистрация: 24.6.2003 Где: Europe::Ukraine:: Kiev Репутация: 16 Всего: 98 |
в смысле "рабатывает только второй вызов этой функции"?
в чем это выражается? -------------------- Tempora mutantur, et nos mutamur in illis... |
|||
|
||||
Void |
|
||||||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Проблема проявляется из-за того, что оператор >> оставляет в потоке '\n', gets читает его и тут же завершается. Можно убедиться на следующем примере:
Лечение простое:
Манипулятор ws поскипает пробелы и служебные символы. Да, и еще: мешать потоки и C stdio - плохая затея. Вместо gets воспользуйся лучше cin.getline:
-------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
||||||
|
|||||||
bilbobagginz |
|
|||
![]() Naughtius Maximus ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8813 Регистрация: 2.3.2004 Где: Israel Репутация: 3 Всего: 317 |
и вообще КТО ЭТОТ Data_book ?!
![]() где он объявлен ? ![]() какого черту далась тебе эта функция в инструкции которой написано: НЕ ИСПОЛЬЗУЙТЕ ЭТУ ФУНКЦИЮ. ? -------------------- Я ещё не демон. Я только учусь. |
|||
|
||||
blackofe |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 29.11.2005 Репутация: 4 Всего: 4 |
оффтоп, но вспомнилось просто из spaceballs: там в звездолете кнопка большая и красная: "аварийная остановка. ни в коем случае не нажимать!" ![]() |
|||
|
||||
Vendigo |
|
||||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
Привет!
Спасибо за оперативность. Я понял... что я почти ничего не понял. Я еще не знаю что такое потоки. Разбирался с структурами и составил эту учебную программку. 2 bilbobagginz Вот Data_book:
Ты имеешь ввиду gets()? Не знал, что ее нельзя использовать ![]() |
||||
|
|||||
Void |
|
||||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
cin/cout - это стандартные потоки ввода-вывода.
Эта функция не проверяет, не выходят ли введенные данные за пределы выделенного буфера. Поэтому ее категорически не рекомендуется использовать. Вместо нее следует применять fgets или istream::getline. -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
||||
|
|||||
blackofe |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 29.11.2005 Репутация: 4 Всего: 4 |
я со всем согласен, но напрашиваются параллели. ведь char a[20] тоже нельзя использовать - потому что легко можно выйти за пределы строки. и какой-нибудь strcat() тоже нельзя использовать. а указатели совершенно не рекомендуется использовать - мало ли что с их помощью можно натворить! а уж new - просто под замок - потому что сплошь и рядом забывают вызывать ответный delete. вывод: не программируйте, други мои. это опасно для жизни. ни в коем случае не наезд и не попытка растления неопытных. но согласитесь, логика таки в моих словах есть. ![]() |
|||
|
||||
Void |
|
||||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Из вышесказанного, ИМХО, следует несколько иной вывод: не программируйте на C++ - это опасно для жизни. ![]() Прошу не воспринимать как призыв к холивару - просто настроение у меня такое ![]()
Дао, высказанное словами, не есть Дао. ![]() Так что, действительно, давайте не будем растлевать малолетних ![]() -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
||||
|
|||||
blackofe |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 29.11.2005 Репутация: 4 Всего: 4 |
deal ![]() а настроение, действительно, того.. только клопов давить под такое настроение ![]() |
|||
|
||||
dronzo |
|
|||
Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 26.11.2005 Где: Москва Репутация: 1 Всего: 8 |
Void, Это не холивар, это ты Страуструпа цитируешь : "Программируя на С вы легко можете прострелить себе ногу, программируя на С++ - это сделать сложнее, но если вы это сделаете, то вам оторвёт ногу целиком". ![]() |
|||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
dronzo
Так и быть, спрячусь за Мастера ![]() -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
DrLazy |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 8.7.2005 Репутация: нет Всего: нет |
dronzo
Вывод, не цельтесь себе в ногу, даже в шутку ![]() |
|||
|
||||
Vendigo |
|
||||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
Привет всем, это опять я. Изучение продвигается, сейчас я осваиваю классы. Предыдущий пример со структурой я переписал в виде класса:
Создал массив объектов:
Но опять таки все уперлось в получение строки из консоли. Void пишет, что можно использовать fgets() (вместо gets() которая не работает). Нашел её прототип в справке: char *fgets(char *s, int n, FILE *stream); Объясните параметр FILE *stream, про потоки я еще ничего не знаю, так что... помогите. |
||||
|
|||||
Vendigo |
|
|||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
Несколько соображений по поводу классов. Хочу узнать у вас правильно ли я их понимаю.
Объекты, которые определяются на основе классов, объединяют в себе данные и методы с помощью которых можно работать с этими данными. Данные нужно описывать в закрытой части класса, чтобы ограничить их использование вне класса. Таким образом данные становятся недоступны из программы, невидимы. Что бы работать с данными нужно использовать методы - функции которые описаны в открытой части класса. В этих функциях нужно проверять правильность ввода/вывода значений в/из закрытых данных, тем самым защищая их. То есть в описанном мною классе Data_list в поле int birthday храниться дата рождения. А через функцию int birthday_put(int a) я получаю эту дату. И в ней я должен предусмотреть что бы вводимое значение являлось действительной датой. Например функция будет возвращать 1 если пользователь ввел правильный формат и полю birthday присвоено значение. И 0, если формат не верен, и данные не записаны. А в программе я буду обрабатывать эти значения. Так? Добавлено @ 19:24 Еще небольшой вопрос. Я работаю в Builder 6, и слева от текста кода, в проводнике, у меня отображается структура класса. Так вот когда я меняю объявление класса эта структура не меняется. Подскажете, как это лечится. |
|||
|
||||
Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
Вообщето
то для работы с файлами , имхо. -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. ![]() |
|||
|
||||
Vendigo |
|
||||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
Млин, товарищи сертифицированные специалисты. Может разьясните как правильно получить строку из консоли?
А то чегой то у меня ![]() Вот полный текст программы:
Так тож не получается:
Это сообщение отредактировал(а) Vendigo - 18.1.2006, 20:02 |
||||
|
|||||
asdf |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 144 Регистрация: 27.8.2004 Где: Кишинёвъ Репутация: нет Всего: 11 |
Это сообщение отредактировал(а) asdf - 18.1.2006, 22:06 --------------------
... |
|||
|
||||
asdf |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 144 Регистрация: 27.8.2004 Где: Кишинёвъ Репутация: нет Всего: 11 |
ещё ты можешь получать доступ к закрытым членам класса, указав функцию не являющуюся членом, как friend в его объявлении.
--------------------
... |
||||
|
|||||
Vendigo |
|
|||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
Спасибо asdf, вроде работает. Сейчас уже поздно, завтра буду разбираться.
![]() ![]() ![]() |
|||
|
||||
Vendigo |
|
|||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
1. Все, разобрался
![]() Оказывается у меня и здесь еще была ошибка:
я получал первый символ а не указатель на него! 2. Подскажите пожалуйста функцию которая возвращает код символа. Перерыл все свои книги и весь форум не могу найти такой простой вещи. |
|||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Ее нет ![]() -------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
Mayk |
|
||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Просто кастаните в int.
Теперь потабаним. Почти согласен. Только не так категарично. strcat действительно не следует использовать в общем случае. Точно так же как не стоит использовать strcpy и sprintf. Вместо них лучше использовать strncat, strncpy, snprintf (пример из жизни - скаченная и собранная quake1 у меня вылетала, так как там в Sys_Printf использовали vsprintf на 1024 байтный буфер, а строка(которая содержала всякие характеристики видюхи, и вообще была юзеру(мне) не нужна) получалась более 1024 символов. Результат - Segmentation fault). Про new - есть такие замечательные штуки как auto_ptr и shared_ptr, которые при определенным стечении обстоятельств позволят избежать утечек памяти и не вызывать delete. Указатели порой действительно можно заменить ссылками, что а) предотвратит передачи NULL'а, и кроме того б) увеличит скорость разработки , так как вместо "if(a) a->b" можно будет писать "a.b" :-) Вывод: используйте безопасные функции, и ваши волосы будут мягкими и пушистими. Соглсен ![]() зы. Вот чем хорош стандарт - там ф-ции snprintf и sprintf описываются рядом. Во всяких книжках "с++ за обеденный перерыв" (во всяком случае в тех, что попадались мне) такого можно не дождаться. Кстати, в С99 ф-ция snprintf(7.19.6.5) описывается ДО sprintf(7.19.6.6) ![]() Это сообщение отредактировал(а) Mayk - 20.1.2006, 20:52 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||
|
|||||
Vendigo |
|
|||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
Void
Mayk Спасибо! Всего труднее найти то, что у тебя перед глазами ![]() Можете еще объяснить про кодировки? Я сделал так:
И получил таблицу символов. Так эти символы отображаются в консоли. Что то мне подсказывает что в оконном приложении символы были бы другие (или расположенны по другому). И еще такой вопрос: |
|||
|
||||
blackofe |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 29.11.2005 Репутация: 4 Всего: 4 |
вполне возможно. хотя бы потому, что оконное приложение могло использовать windows-кодировку, а консольное - dos-кодировку. про кодировку тут говорили не раз. воспользуйся поиском. к примеру, можно поискать слово "locale". |
|||
|
||||
Fin |
|
|||
![]() Дракон->Спать(); ![]() ![]() Профиль Группа: Участник Сообщений: 687 Регистрация: 4.1.2006 Репутация: 3 Всего: 10 |
Что то тебе подсказывает правильно. Досовская русская кодировка (CP-866) отличается от кодировки Винды (Windows-1251) в верхней части таблици. До символа с номером 127 все кодировки повторяются. Как выглядит кодировка можно посмотреть Character Map которая идет в комплекте постаки винды. Там нужно вызвать на показ любой шрифт соответствуюший кодировке винды. Я например смотрю или Arial или Courier New Cyr. -------------------- Пролетал мимо. |
|||
|
||||
asdf |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 144 Регистрация: 27.8.2004 Где: Кишинёвъ Репутация: нет Всего: 11 |
переоткрытием проекта. если перед изменением объявления ты переходишь к нему 2х кликом в проводнике классов, структура должна правиться сходу .... --------------------
... |
|||
|
||||
Vendigo |
|
|||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
Ничего не понимаю
![]() Я написал код который как я думаю выводит DOS кодировку символов. Но обратное преобразование не получается т.е. (int)c возвращает странный код. Например если char c = 'б' то (int)c = -95 ![]()
|
|||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
Объяви c, как unsigned char.
-------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
Vendigo |
|
|||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
Все понял! Спасибо Void
![]() Если у меня char то коды лежат в пределах от -128 до 127 ! Чтоб я делал без этого форума! |
|||
|
||||
Vendigo |
|
||||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
Всем доброго времени суток
![]() Главный вопрос, конечно же, остался: Смогу ли я когда-нибудь выучить этот С++? И если да, то сколько мне его еще штудировать? Но появляются и более "низменные" вопросы. Так в главе "Перегрузка операторов" автор рассматривает создание своего класса строк:
Вопрос такой: Зачем в этом классе перегрузка оператора присваивания? Ведь класс не содержит в своих данных указателей. Операция присваивания, которая определена по умолчанию (побитовая копия) прекрасно работает. Зачем огород городить? И второй вопрос: Присваивание строки с завершающим нулем. Имхо так было бы проще:
|
||||
|
|||||
Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Наверное, чтобы не копировать три сотни символов, если можно меньше скопировать. А вообще strcpy надо заменить на strncpy(); А то на длинных строках будет ой. В operator'ах и конструкторе char* заменить на const char*, и возвращать в operator='ах не str_type, а str_type&. -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
Vendigo |
|
|||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
Насколько я понимаю, const char* в параметрах служит для того, чтобы функция не могла изменить переданный ей аргумент. А это что значит? "возвращать в operator='ах не str_type, а str_type&." ( Я знаю, только, что &a значит "Получить адрес переменной а" ) |
|||
|
||||
Lotrex |
|
||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 95 Регистрация: 9.2.2006 Где: Казань Репутация: 2 Всего: 3 |
Это значит, что фактически (на уровне команд) будет возвращатся не значение, а указатель. На уровне С++ будет отличие - такой указатель назыв. ссылкой, но разыменовывать его не надо - он как бы уже разыменован, и с ним надо обращатся как с переменной, содержащей некоторое значение, а не адрес. Отсюда существенное отличие записей
и
отличия будут в выражениях типа следующего:
В первом случае значение возвращаемого пр-ра будет копироватся дважды - один раз внутри оператора b = c (при вызове оператора return str; где str имеет тип str_type) произойдет копирование в стек, потом - передача адреса содержимого стека в качестве входного параметра в операторе a = b. Во втором случае в стек сначала будет копироватся значение не содержимого str, а ее адреса, и если str будет автоматической (стековой) переменной, то во втором операторе (a = b) произойдет ошибка. Это сообщение отредактировал(а) Lotrex - 15.2.2006, 09:09 |
||||||
|
|||||||
Vendigo |
|
||||||||||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
Добрый вечер всем кто в сети
![]() Упражнялся я со своим Builderom и в результате неких экспериментов накопил к вам ряд вопросов. Допустим мне нужно чтоб функция возвращала двумерный массив. Например такой
Целиком массив из функции вернуть нельзя, так же как нельзя в нее массив передать. Для этого используется указатель на первый элемент массива так? Но как оказалось недостаточно объявить ф-ию:
и в ней написать
компилятор ругается "E2034 Cannot convert 'int ( *)[25]' to 'int *'" – не знаю, что это значит. Хоть учебник и утверждает, что "использование имени массива без индекса генерирует указатель на первый элемент" Я поступил таким образом:
И только было возрадовался своей хитрости, сумевшей обмануть компилятор, как обнаружил, что программа все равно не работает!!! Меня ждало жестокое разочарование! Массив созданный внутри функции, суть локальные переменные, и указатель на его начало, никоим образом мне помочь не может. Как только функция завершается память тотчас освобождается. В итоге я остался там же где и начал. Неужели нет способа возвратить из функции массив? Весь код:
|
||||||||||
|
|||||||||||
sergejzr |
|
|||
![]() Un salsero ![]() Профиль Группа: Админ Сообщений: 13285 Регистрация: 10.2.2004 Где: Германия г .Ганновер Репутация: 19 Всего: 360 |
Модератор: Название темы должно отражать ее суть!
Модератор: Пожалуйста, один топик - один вопрос. |
|||
|
||||
Vendigo |
|
|||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
И другой вопрос, уже не такой философско-риторический, допустим, я хочу передать двумерный массив в функцию.
И использую указатель int *d в ее параметре. Как мне обращаться к элементам этого массива? d[i][j] – не работает (в принципе понятно почему) писать что то вроде этого: d[i*r+j] , где r – длинна строки в массиве? |
|||
|
||||
MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
может d[i*(r-1)+j], в C/C++ обычно первый индекс 0 Добавлено @ 22:07
либо память динамически выделять, либо пользоваться std::vector, можешь написать свой класс, ... -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
Vendigo |
|
|||
Новичок Профиль Группа: Участник Сообщений: 40 Регистрация: 25.9.2005 Где: Челябинская обл. г. Миасс Репутация: нет Всего: нет |
||||
|
||||
Void |
|
|||
![]() λcat.lolcat ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2206 Регистрация: 16.11.2004 Где: Zürich Репутация: 40 Всего: 173 |
-------------------- “Coming back to where you started is not the same as never leaving.” — Terry Pratchett |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |