C++ Перегрузка оператора ››

Мне нужно перегрузить оператор извлечения потока. Мне нужно сделать это, разрешив пользователю вводить строку символов в приглашении, скажем, «iamastring», а затем оператор будет извлекать каждый символ из строки и проверять, является ли это пробелом, и если это не хранилище пробелов. это в массиве символов, который затем передается объекту.

@Чип и др. Например, вывод. Я не ожидаю, что он что-то выведет на экран. Вместо этого после того, как пользователь введет строку и нажмет Enter, пользователю снова будет предложено ввести новый пункт меню. В настоящее время пользователь вводит строку, нажимает ввод, а затем отображается «плохая ошибка чтения», и снова появляется подсказка в ожидании нового ввода.


person ihtkwot    schedule 06.12.2009    source источник
comment
Вы были программистом C в прошлой жизни?   -  person Paul    schedule 06.12.2009
comment
оператор ›› — оператор ИЗВЛЕЧЕНИЯ потока   -  person    schedule 06.12.2009
comment
У вас течет буфер. Вместо этого вы должны использовать std::vector. Тем не менее, просто используйте getline и string, как предложил Нил. Ваша жизнь станет намного проще.   -  person GManNickG    schedule 06.12.2009
comment
@Paul, я не был программистом на C в прошлой жизни, я учусь программировать на C++ и @Neil, спасибо за редактирование :)   -  person ihtkwot    schedule 06.12.2009
comment
@GMan, что ты имеешь в виду под утечкой моего буфера? Управление памятью, безусловно, является моим слабым звеном, поэтому я не понимаю, как то, как я структурировал вещи, может привести к утечке.   -  person ihtkwot    schedule 06.12.2009
comment
@Chip, спасибо, я отредактировал пост, в моем фактическом коде он не написан таким образом, я просто набрал его неправильно.   -  person ihtkwot    schedule 06.12.2009
comment
Не могли бы вы также привести пример вывода: чего вы ожидаете и что получаете от рутины?   -  person Chip Uni    schedule 06.12.2009
comment
Вы никогда не звонили delete [] buffer. Каждый new должен соответствовать delete. std::vector делает это за вас.   -  person GManNickG    schedule 06.12.2009
comment
@GMan Спасибо, это была глупая ошибка. Я не использовал std::vector, но, возможно, я посмотрю на него прямо сейчас, чтобы посмотреть, смогу ли я понять синтаксис и функциональность.   -  person ihtkwot    schedule 06.12.2009
comment
Определенно. Он действует как обычный динамический массив, но выполняет всю неприятную работу за вас, например, изменение размера и т. д. На самом деле вам, вероятно, больше не нужно выделять определенный размер. Используйте функцию push_back, чтобы добавить значение к вашему массиву, и вектор изменит размер за вас.   -  person GManNickG    schedule 06.12.2009
comment
Как вы думаете, если бы я удалил аспект массива из своего решения и заменил его вектором, это решило бы реальную проблему ввода? Мне неясно, как это будет связано с реальной проблемой чтения символов из потока.   -  person ihtkwot    schedule 06.12.2009
comment
Нет, но это должно упростить его. (Или, может быть, я не уверен)   -  person GManNickG    schedule 06.12.2009
comment
Он никогда не публиковал полный листинг кода, так что технически мы пока не знаем, произошла утечка буфера или нет, хотя я подозреваю, что да.   -  person s1n    schedule 06.12.2009
comment
@ s1n и др., Логичен ли код? Я имею в виду, что то, что я опубликовал, похоже на то, что оно берет символ из потока посимвольно?   -  person ihtkwot    schedule 06.12.2009
comment
Есть пара небольших проблем с ifs. Мне не очень нравится endoffile != true, это было бы более лаконично, чем !endoffile. То же самое и с isspace, кажется, проще читать как isspace(ch) или !isspace(ch). После проверки if ( isspace(ch) )... вам не нужно проверять обратное в предложении else.   -  person David Rodríguez - dribeas    schedule 07.12.2009
comment
Также вы можете проверить, что вы делаете... кажется, что у вас может быть переключение внутренних ifs (вы проверяли, сохраняете ли вы только пробелы в буфере?)   -  person David Rodríguez - dribeas    schedule 07.12.2009


Ответы (3)


Это довольно забавно - твое имя похоже на мое, но наоборот :)

Как насчет:

char buffer[buffSize+1]; // no need for dynamic allocation here
unsigned i = 0;
while(std::cin && !std::isspace(std::cin.peek()) && i < buffSize)
  buffer[i++] = std::cin.get();
buffer[i] = '\0'; // null termination can be important.
// i now contains the length btw

Это точно ваш собственный код, только немного переработанный - я удалил все лишнее и т.д., больше ничего..

Изменить: теперь исправлено для проверки статуса потока и предотвращения переполнения стека :)

Редактировать II: изменено std::cin.good() && !std::cin.eof() на std::cin. Кстати: почему cin имеет преобразование в void*, а не в bool?

person rmn    schedule 06.12.2009
comment
Это было полезно и чисто. Я закончил с вариацией этого кода. - person ihtkwot; 07.12.2009
comment
+1 — cin.good() && !cin.eof() можно (и нужно!) заменить просто на cin. Потоки можно оценивать в логическом контексте (их «свежесть»), и это канонический C++. - person Konrad Rudolph; 07.12.2009
comment
Конард, вы абсолютно правы - я просто хотел оставаться как можно ближе к данному коду. Хотя сейчас отредактировал. - person rmn; 07.12.2009
comment
Вы также можете сделать этот дубль любой длины, используя vector + push_back. - person GManNickG; 07.12.2009

Есть ли причина, по которой вы не используете std::string и std::getline? Вы должны подумать дважды или даже трижды, прежде чем писать свой собственный оператор извлечения - форматированный ввод не является особенно полезной функцией C++ (или C, если уж на то пошло).

person Community    schedule 06.12.2009
comment
Я всегда с сомнением отношусь к любому учебному курсу, который мешает вам использовать самый простой подход к проблеме. Я пишу код на C++ уже более 20 лет и могу сосчитать по пальцам одной руки, сколько раз я реализовал оператор извлечения потока. - person ; 06.12.2009
comment
Да, мы все должны платить волынщику. Я предполагаю, что некоторые назвали бы это упражнение немного педантичным, но всегда есть чему поучиться, снова и снова ударяя головой по клавиатуре... Я думаю. - person ihtkwot; 06.12.2009

В любом случае код сломан. Он не обрабатывает ошибки ввода, которые могут быть фатальными, поскольку ваш код может войти в бесконечный цикл. Если вы инкапсулируете операции чтения потока, вы должны позаботиться о том, чтобы проверить, находится ли поток в допустимом состоянии.

person Konrad Rudolph    schedule 06.12.2009
comment
поэтому я хотел бы проверить, что ios::goodbit == true, а затем войти в мой цикл? - person ihtkwot; 07.12.2009
comment
Потоковые биты работают не так. ios::goodbit - это просто константа. Кроме того, == true просто избыточен. Смотрите обновленный ответ @rmn для правильного (хотя и неканонического) способа сделать это. - person Konrad Rudolph; 07.12.2009