246071-Либерти-Освой-самостоятельно-С-за-21-день (852741), страница 80
Текст из файла (страница 80)
В качестве переменнойчленаклассаiosвыступаетобъектstreambuf.•Классыistreamиostreamявляютсяпроизводнымиотклассаiosиотвечаютсоответственнозапотоковыйвводивыводданных.• Класс iosteam является производным от классов istream и ostream и обеспечивает методыввода-выводадляпечатинаэкран.•Классыfstreamиспользуютсядляввода-выводаизфайлов.Стандартныеобъектыввода-выводаПризапускепрограммы,включающейклассыiostreams,создаютсяиинициируютсячетыреобъекта.Примечание:Библиотекаклассаiostreamвстроенавкомпилятор.Чтобыдобавитьвсвоюпрограмму методы этого класса, достаточно в первых строках программы включитьвыражение#include<iostream>.• Объект cin (произносится как "си-ин" от английского "see-in") обрабатывает ввод склавиатуры.• Объект cout (произносится как "си-аут" от английского "see-out") обрабатывает вывод наэкран.• Объект cerr (произносится как "си-эр" от английского "see-err") обрабатывает небуферизированныйвыводошибокнастандартноеустройствовыводасообщенийобошибках,т.е.наэкран.Посколькувыводнебуферизированный,товседанные,направляемыевcerr,сразужевыводятсяустройствомвывода.• Объект clog (произносится как "си-лог" от английского "see-log") обрабатываетбуферизированныесообщенияобошибках,которыевыводятсянастандартноеустройствовыводасообщений об ошибках (экран).
Зачастую эти сообщения переадресуются в файл регистрации.Обэтомвыузнаетедалеевглаве.ПереадресацияКаждоестандартноеустройствовводаивывода,втомчислеустройствовыводасообщенийоб ошибках, может осуществлять переадресацию на другие устройства. Например, системныесообщения об ошибках часто переадресуются в файл регистрации.
Для ввода и вывода данныхпрограммой также можно использовать файлы, для чего служат специальные командыоперационнойсистемы.Под переадресацией понимают пересылку выводимых данных в устройство, либосчитываниеданныхсустройства,отличноеотустановленногопоумолчанию.ВоперационныхсистемахDOSиUNIXиспользуютсяспециальныеоператорыпереадресацииввода(<)ивывода(>).Пайпингом называется использование вывода одной программы в качестве ввода длядругой.Операционная система DOS содержит ограниченный набор команд переадресации длявывода (>) и ввода (<).
Команды переадресации системы UNIX более разнообразны, однакоосновная идея остается той же: данные выводятся на экран, записываются в файл илипередаютсядругойпрограмме.Вводвпрограммуосуществляетсяизфайловилисклавиатуры.В целом переадресация больше относится к функциям операционной системы, а небиблиотек iosream. Язык C++ предоставляет доступ к четырем стандартным устройствам инеобходимыйнаборкоманддляпереадресацииустройствввода-вывода.ВыводданныхспомощьюcinГлобальныйобъектcinотвечаетзавводданныхистановитсядоступнымпривключениивпрограмму класса iostream.
В предыдущих примерах используется перегруженный операторввода (>>) для присвоения вводимых данных переменным программы. Для ввода данныхиспользуетсяследующийсинтаксис".intsomeVariable;cout<<"Enterаnumber:";cin>>someVariable;Другой глобальный объект, cout, и его использование для вывода данных обсуждаетсянесколько ниже.
Сейчас же остановимся на третьей строке: cin >> someVariable;. Что жепредставляетсобойобъектcin?На глобальность этого объекта указывает тот факт, что его не нужно объявлять в кодепрограммы. Объект cin включает перегруженный оператор ввода (>>), который записываетданные,хранимыевбуфереcin,влокальнуюпеременнуюsomeVariable.Причемоператорвводаперегружен таким образом, что подходит для ввода данных всех базовых типов, включая int&,short&,long&,double&,float&,char&,char*ит.п.Когдакомпиляторвстречаетвыражениеcin>>someVariable, то вызывается вариант оператора ввода, соответствующий типу переменнойsomeVariable. В приведенным выше примере someVariable имеет тип int, поэтому вызываетсяследующийвариантперегруженнойфункции:istream&operator>>(int&)Обратите внимание, поскольку параметр передается как ссылка, оператор ввода можетизменятьисходнуюпеременную.Использованиеcinпоказановлистинге16.1.Листинг16.1.Использованиеcinдлявводаданныхразныхтипов1://Листинг16.1.Вводданнахспомощьюcin2:3:#include<iostream.h>4:5:intmain()6:{7:intmyInt;8:longmyLong;9:doublemyDouble;10:floatmyFloat;11:unsignedintmyUnsigned;12:13:cout<<"int:";14:cin>>myInt;15:cout<<"Long:";16:cin>>myLong;17:cout<<"Double:";18:cin>>myDouble;19:cout<<"Float:";20:cin>>myFloat;21:cout<<"Unsigned:";22:cin>>myUnsigned;23:24:cout<<"\n\nInt:\t"<<myInt<<endl;25:cout<<"Long:\t"<<myLong<<endl;26:cout<<"Double:\t"<<myDouble<<endl;27:cout<<"Float:\t"<<myFloat<<endl;28:cout<<"Unsigned:\t"<<myUnsigned<<endl;29:return0;30:}Результат:int:2Long:70000Double:987654321Float:3.33Unsigned:25Int:2Long:70000Double:9.87654e+08Float:3.33Unsigned:25Анализ: В строках 7—11 объявляются переменные разных типов.
В строках 13—22пользователю предлагается ввести значения для этих переменных, после чего результатывыводятсявстроках24—28(спомощьюcin).Выводимая программой информация говорит о том, что переменные записываются ивыводятсявсоответствиисихтипом.СтрокиОбъект cin также может принимать в качестве аргумента указатель на строку символов(char*), что позволяет создавать буфер символов и заполнять его с помощью cin.
Например,можнонаписатьследующее:charYourName[50]cout<<"Enteryourname:";cin>>YourName;Если ввести имя Jesse, переменная YourName заполнится символами J, e, s, s, e и \0.Последним будет концевой нулевой символ, так как cin автоматически вставляет его. Поэтомуприопределенииразмерабуферанужнопозаботитьсяотом,чтобыонбылдостаточнобольшими мог вместить все символы строки, включая концевой нулевой символ. Более подробно оподдержкеконцевогонулевогосимволастандартнымибиблиотечнымистроковымифункциямиречьпойдетназанятии21.Проблемы,возникающиепривводестрокУспешно выполнив все описанные ранее операции с объектом cin, вы будете неприятноудивлены, если попытаетесь ввести в строке полное имя.
Дело в том, что cin рассматриваетпробелкакзаданныйпоумолчаниюразделительстрок.Послетогокаквстрокеобнаруживаетсяпробел, ввод строки завершается добавлением концевого нулевого символа. Эта проблемапоказанавлистинге16.2.Листинг16.2.Попыткавводабодеводногосшаспомощьмcin1://Листинг16.2.Проблемысвводомстрокиспомощьюcin2:3:#include<iostream.h>4:5:intmain()6:{7:charYourName[50];8:cout<<"Yourfirstname:";9:cin>>YourName;10:cout<<"Hereitis:"<<YourName<<endl;11:cout<<"Yourentirename:";12:cin>>YourName;13:cout<<"Hereitis:"<<YourName<<endl;14:return0;15:}Результат:Yourfirstname:JesseHereitis:JesseYourentirename:JesseLibertyHereitis:JesseАнализ: Строкой 7 для хранения вводимой пользователем строки создается массивсимволов.
В строке 8 пользователю предлагается ввести имя, и, как видно из вывода, это имясохраняетсяправильно.В строке 11 пользователю предлагается ввести не только имя, но и фамилию. Вводосуществляется только до тех пор, пока cin не обнаружит пробел между именем и фамилией.Послеэтоговводстрокипрекращаетсяиоставшаясяинформациятеряется.Этонесовсемто,чтобылонужно.Чтобы понять, почему cin работает именно так, проанализируйте листинг 16.3, в которомпоказанпримервводастрокизначений.Листинг16.3.Вводстрокизначений1://Листинг16.3.Вводстрокизначенийспомощьюcin2:3:#include<iostream.h>4:5:intmain()6:{7:intmyInt;8:longmyLong;9:doublemyDouble;10:floatmyFloat;11:unsignedintmyUnsigned;12:charmyWord[50];13:14:cout<<"int:";15:cin>>myInt;16:cout<<"Long:";17:cin>>myLong;18:cout<<"Double:";19:cin>>myDouble;20:cout<<"Float:";21:cin>>myFloat;22:cout<<"Word:";23:cin>>myWord;24:cout<<"Unsigned:";25:cin>>myUnsigned;26:27:cout<<"\n\nInt:\t"<<myInt<<endl;28:cout<<"Long:\t"<<myLong<<endl;29:cout<<"Double:\t"<<myDouble<<endl;30:cout<<"Float:\t"<<myFloat<<endl;31:cout<<"Word:\t"<<myWord<<endl;32:cout<<"Unsigned:\t"<<myUnsigned<<endl;33:34:cout<<"\n\nInt,Long,Double,Float,Word,Unsigned:";35:cin>>myInt>>myLong>>myDouble;36:cin>>myFloat>>myWord>>myUnsigned;37:cout<<"\n\nInt:\t"<<myInt<<endl;38:cout<<"Long:\t"<<myLong<<endl;39:cout<<"Double:\t"<<myDouble<<endl;40:cout<<"Float:\t"<<myFloat<<endl;41:cout<<"Word:\t"<<myWord<<endl;42:cout<<"Unsigned:\t"<<myUnsigned<<endl;43:44:45:return0;46:}Результат:Int:2Long:30303Double:393939397834Float:3.33Word:HelloUnsigned:85Int:2Long:30303Double:3.93939e+11Float:3.33Word:HelloUnsigned:85Int,Long.Double,Float,Word,Unsigned:33049383938474736.66bye-2Int:3Long:304938Double:3.93847e+08Float:6.66Word:byeUnsigned:4294967294Вновь в программе объявляются переменные разных типов и массив символов.Пользователюпредлагаетсяпоследовательноввестиданныеразныхтипов,чтобыубедитьсячтопрограммаподдерживаетвводданныхлюбоготипа.Анализ: В строке 34 пользователю предлагается ввести все данные сразу в определенномпорядке, после чего каждое введенное значение присваивается соответствующей переменной.Благодаря тому что cin рассматривает пробелы между словами как разделители, становитсявозможной инициализация всех переменных.
В противном случае программа пыталась быввестивсюстрокуводнупеременную,чтобылобыошибкой.Обратите внимание на строку 42, в которой выводится без знаковое целое число.Пользователь ввел значение -2. Поскольку программа была проинструктирована, что вводитсябез знаковое целое число, то вместо знакового -2 будет введено без знаковое двоичноепредставление этого числа. Поэтому при выводе с помощью cout на экране отображаетсязначение4294967294,являющеесядвоичнымпредставлениемчисла-2.Позже вы узнаете, как вводить в буфер строки, содержащие несколько слов, разделенныхпробелами.
Сейчас же рассмотрим подробнее использование cin для ввода данных сразу внесколькопеременных,каквстроках35-36.Оператор>>возвращаетссылкунаобъектistreamОператор>>возвращаетссылкунаобъектistream.Нопосколькуcinсамявляетсяобъектомistream,результатвыполненияоднойоперациивводаможетбытьначаломследующейоперацииввода,какпоказанониже:IntVar0ne,varTwo,varThree;cout<<"Enterthreenumbers:"cin>>Var0ne>>varTwo>>varThree;В строке cin >> VarOne >> varTwo >> varThree; сначала выполняется первый ввод cin >>VarOne, в результате чего возвращается объект istream, позволяющий выполнить присвоениевторогозначенияпеременнойvarTwo.Эторавносильноследующейзаписи:((cin>>VarOne)>>varTwo)>>varThree;Аналогичныйподходиспользуетсясобъектомcout,норечьобэтомпойдетдальше.ДругиеметодыобъектаcinВ дополнение к перегружаемому оператору >> объект cin имеет множество другихвстроенных методов.