246071-Либерти-Освой-самостоятельно-С-за-21-день (852741), страница 82
Текст из файла (страница 82)
В строке 9 пользователюпредлагаетсяввестистроку.Внашемпримеревводитсястрокаonceuponаtime.Вводзавершаетсянажатием<Enter>.Встроке10длясчитыванияэтойстрокииспользуетсяфункцияget(),котораяприсваивает эту строку переменной stringOne и останавливается на символе начала новойстроки,оставляяеговбуфереввода.В строке 13 пользователю еще раз предлагается ввести вторую строку, однако в этот разфункцияgetline()встроке14считываетсимволразрывастроки,оставшийсявбуфере,исразужезавершаетсвоюработу.В строке 19 пользователю предлагается ввести первую строку.
Однако в этом случае дляпропускасимволаразрывастрокииспользуетсяфункцияignore()(см.влистинге16.8строку23).Таким образом, при вызове getline() строкой 26 буфер ввода пуст, и пользователь получаетвозможностьввестиследующуюстроку.Функции-членыpeek()иputback()Объект cin обладает двумя дополнительными методами, которые могут оказаться весьмаполезными. Метод peek()просматривает, но не считывает очередной символ. Метод putback()вставляетсимволвпотокввода.Использованиеэтихметодовпоказановлистинге16.9.Листинг16.9.Использованиефункцийpeek()Вputback()1://Листинг16.9.Использованиеpeek()иputback()2:#include<iostream.h>3:4:intmain()5:{6:charch;7:cout<<"enterаphrase:";8:while(cin.get(ch))9:{10:if(ch=='!')11:cin.putback('$');12:else13:cout<<ch;14:while(cin.peek()=='#')15:cin.ignore(1,'#');16:}17:return0;18:}Результат:enterаphrase:Now!is#the!time#for!fun#!Now$isthe$timefor$fun$Анализ: В строке 6 объявляется символьная переменная ch, а в строке 7 пользователюпредлагаетсяввестистрокутекста.Назначениеэтойпрограммысостоитвтом,чтобызаменитьвсевстречающиесявовведеннойстрокевосклицательныезнаки(!)знакомдоллара($)иудалитьвсесимволы(#).Цикл while в теле функции main() программы прокручивается до тех пор, пока не будетвозвращенсимволконцафайла(вводитсякомбинациейклавиш<Ctrl+C>вWindowsили<Ctrl+Z>и<Ctrl+D>вMSDOSиUNIXсоответственно).(Незабывайте,чтофункцияcin.get()возвращает0вконцефайла.)Еслитекущийсимволоказываетсявосклицательнымзнаком,онотбрасывается,авпотоквводафункциейputback()возвращаетсясимвол$.Еслижетекущийсимволнеявляетсявосклицательным знаком, он выводится на экран.
Если текущий символ оказывается #, то онпропускаетсяфункциейignore().Указанный подход далеко не самый эффективный способ решения подобных задач (болеетого,еслисимвол#будетрасположенвначалестроки,топрограммаегопропустит).Нонашаосновная цель состояла в том, чтобы продемонстрировать работу функций putback() и ignore().Впрочем,ихиспользованиедостаточнопростоипонятно.Примечание:Методы peek() и putback() обычно используются для синтаксическогоанализастрок.Необходимостьвнемвозникает,например,присозданиикомпилятора.ВводданныхспомощьюcoutРанее вы уже использовали объект cout вместе с перегруженным оператором вывода (<<)для выведения на экран строк, чисел и других данных. Этот объект позволяет такжеформатировать данные, выравнивать столбцы и выводить числовые значения в десятичном ишестнадцатеричномформате.Какэтосделать,выузнаетедалее.ОчисткабуферавыводаВы, вероятно, уже заметили, что использование endl приводит к очистке буфера вывода.Этот оператор вызывает функцию-член flush() объекта cout, которая и осуществляет очисткубуфера.
Вы можете напрямую вызывать метод flush(), либо вызвав функцию-член flush(), либонаписавследующеевыражение:cout<<flushУказанный метод позволяет явно очистить буфер вывода на тот случай, если не всяинформацияизнегобылавыведенанаэкран.Функции-членыобъектаcoutАналогичнотому,какмыобращалиськметодамобъектаcin:get()иgetline(),собъектомcoutможноиспользоватьфункцииput()иwrite().Функцияput()выводитодинсимволнастандартноеустройствовывода.Таккакэтафункциявозвращает ссылку на ostream, а cout является объектом ostream, есть возможностьпоследовательного обращения к функции put() для вывода ряда значений, как и при вводеданных.Реализацияэтойвозможностипоказанавлистинге16.10.Листинг16.10.Использованиефункцииput()1://Листинг16.10.Использованиеput()2:#include<iostream.h>3:4:intmain()5:{6:cout.put('H').put('e').put('l').put('l').put('o').put('\n');7:return0;8:}Результат:HelloПримечание:Призапускеэтойпрограммынекоторыекомпиляторыневыведутзаданноеслово Hello.
Если эта проблема коснется и вас, просто пропустите этот листинг и идитедальше.Анализ: Строку 6 можно представить следующим образом: функция cout.put('H') выводитбукву H на экран и возвращает объект cout. Оставшуюся часть выражения можно представитьследующимобразом:cout.put('e').put('l').put('l').put('o').put('\n');Выводится буква e, после чего остается cout.put('l'). Таким образом, повторяется цикл, накаждом этапе которого выводится следующая бука и возвращается объект cout. После выводапоследнегосимвола('\n')выполнениефункциизавершается.Функция write() работает так же, как и оператор ввода (<<), но она принимает параметр,указывающий максимальное количество выводимых символов.
Использование этой функциипоказановлистинге16.11.Листинг16.11.Использованиефункцииwrite()1://Листинг16.11.Использованиеwrite()2:#include<iostream.h>3:#include<string.h>4:5:intmain()6:{7:charOne[]="Oneifbyland";8:9:10:11:intfullLength=strlen(One)12:inttooShort=fullLength-4;13:inttooLong=fullLength+6;14:15:cout.write(One,fullLength)<<"\n";16:cout.write(One,tooShort)<<"\n";17:cout.write(One,tooLong)<<"\n";18:return0;19:}Результат:OneifbylandOneifbyOneifbylandi?!Примечание:Навашемкомпьютерепоследняястрокавыводаможетвыглядетьиначе.Анализ: В строке 7 создается массив символов для заданной строки текста.
Длинавведенного текста присваивается в строке 11 целочисленной переменной fullLength.Установленное значение переменной tooShort меньше этой длины на четыре единицы, азначениепеременнойtooLongбольшенашесть.Встроке15спомощьюфункцииwrite()выводитсявсястрока,посколькувкачествепервогопараметрафункциизадаетсяполнаядлинатекстовойстроки.Строкой 16 вновь выводится строка, однако длина ее на четыре символа меньше, что иотражаетсяввыводе.Еще один вывод данных выполняется в строке 17, однако в этом случае функция write()выводит на шесть символов больше.
После заданной строки на экране появятся символы,расположенныевячейкахпамяти,следующихзаячейкамимассивасимволов.Манипуляторы,флагиикомандыформатированияПоток вывода поддерживает установку большого количества флагов состояния,определяющих основание чисел (десятичное или шестнадцатеричное), ширину полей вывода исимволы, используемые для заполнения полей. Флаг состояния представляет собой байтинформации, каждый бит которого имеет специальное предназначение.
Установка двоичныхфлагов более детально рассматривается на занятии 21. Для установки флагов потока ostreamможноиспользоватьфункции-членыиманипуляторы.Использованиефункцииcout.width()По умолчанию ширина поля вывода автоматически устанавливается такой, чтобы точновместить все символы строки из буфера вывода. Но с помощью функции width() можноустановить точное значение ширины поля вывода.
Эта функция вызывается как метод объектаcout, поскольку является его функцией-членом. Функция width() изменяет ширину толькоследующегополявывода.Использованиеэтойфункциипроиллюстрировановлистинге16.12.Листинг16.12.Настройкашириныполявывода1://Листинг16.12.Настройкашириныполявывода2:#include<iostream.h>3:4:intmain()5:{6:cout<<"Start>";7:cout.width(25);8:cout<<123<<"<End\n";9:10:cout<<"Start>";11:cout.width(25);12:cout<<123<<"<Next>";13:cout<<456<<"<End\n";14:15:cout<<"Start>";16:cout.width(4);17:cout<<123456<<"<End\n";18:19:return0:20:}Результат:Start>123<EndStart>123<Next>456<EndStart>123456<EndАнализ: Сначала (строки 6—8) число 123 выводится в поле шириной в 25 символов.Ширина поля задается в строке 7.
Результат этого форматирования показан в первой строкевывода.Вовторойстрокевыводазначение123распечатываетсяопятьжевполешириной25,азатемсразу же выводится значение 456. Как видите, установка ширины поля применяется толькопервый раз, а для второго выражения с объектом cout уже не действует. Таким образом,установкифункцииwidth()применяютсятолькокследующемувыражениювыводаданных.В последней строке вывода видно, что установка ширины поля меньшей размеразаносимого в него значения игнорируется программой.