246071-Либерти-Освой-самостоятельно-С-за-21-день (852741), страница 83
Текст из файла (страница 83)
В этом случае ширина поляустанавливаетсяравнойразмерамвыводимыхданных.УстановкасимволовзаполненияОбычнообъектcoutзаполняетпробеламипустыепозицииполя,заданныефункциейwidth(),как было показано в приведенном выше примере. Однако иногда возникает необходимостьзаполнить пустые позиции другими символами, например звездочками (*). Для этого нужноиспользовать функцию fill(), в параметре которой указать символ заполнения. Использованиефункцииfill()показановлистинге16.13.Листинг16.13.Использованиефункцииfill()1://Листинг16.13.Функцияfill()2:3:#include<iostream.h>4:5:intmain()6:{7:cout<<"Start>";8:cout.width(25);9:cout<<123<<"<End\n";10:11:12:cout<<"Start>";13:cout.width(25);14:cout.fill('*');15:cout<<123<<"<End\n";16:return0;17:}Результат:Start>123<EndStart>******************123<EndАнализ: Строки 7—9 переписаны из предыдущего листинга.
То же можно сказать и остроках12—15,однаковстроке14этоголистингаиспользуетсяфункцияfill('*')дляустановкисимвола звездочки (*) в качестве символа заполнения, что Наглядно отражается в выводепрограммы.УстановкафлаговДля отслеживания состояния объектов iostream используются флаги. Установку флаговосуществляют с помощью функции setf(), в качестве параметра которой используется одна изстандартныхзаранееустановленныхконстант.Осостоянииобъектаговорятвтомслучае,еслирежимиспользованиянекоторыхиливсехегоданныхможетизменятьсявходеработыпрограммы.Например,можноизменитьрежимотображениячиселизапретитьвыводнаэкраннулевыхдесятичных значений (чтобы число 20,00 выглядело как 20).
Для этого вызывается функцияsetf(ios::showpoint).Область видимости перечисления констант ограничена классом iostream (ios), поэтомунеобходимо использовать явное указание имени константы с именем класса ios::имяфлага,напримерios::showpoint.Длядобавлениязнака"плюс"(+)передположительнымизначениямиустанавливаетсяфлагios::showpos. Чтобы изменить выравнивание выводимых данных на экране влево, вправо и поцентруполявывода,используютсяфлагиios::left,ios::rightиios::intervalсоответственно.Наконец, установка основания отображаемых числовых значений выполняется с помощьюфлагов ios::dec (десятичные числа), ios::oct (восьмеричные числа) или ios::hex(шестнадцатеричные числа).
Эти флаги можно использовать в паре с оператором ввода (<<).Примерустановкифлаговпоказанвлистинге16.4.Листинг16.14.Установкафлаговсппмощьюsetf1://Листинг16.14.Использованиефункцииsetf2:#include<iostream.h>3:#include<iomanip.h>4:5:intmain()6:{7:constintnumber=185;8:cout<<"Thenumberis"<<number<<endl;9:10:cout<<"Thenumberis"<<hex<<number<<endl;11:12:cout.setf(ios::showbase);13:cout<<"Thenumberis"<<hex<<number<<endl;14:15:cout<<"Thenumberis";16:cout.width(10);17:cout<<hex<<number<<endl;18:19:cout<<"Thenumberis";20:cout.width(10);21:cout.setf(ios::left);22:cout<<hex<<number<<endl;23:24:cout<<"Thenumberis";25:cout.width(10);26:cout.setf(ios::internal);27:cout<<hex<<number<<endl;28:29:cout<<"Thenumberis:"<<setw(10)<<hex<<number<<endl;30:return0;31:}Результат:Thenumberis185Thenumberisb9Thenumberis0xb9Thenumberis0xb9Thenumberis0xb9Thenumberis0xb9Thenumberis0xb9Анализ:Встроке7целочисленнаяконстантаnumberинициируетсязначением185,котороевыводитсянаэкранвстроке8.Этожезначениевыводитсястрокой10,однако,посколькуздесьзадействованманипуляторhex,оноотображаетсявшестнадцатеричномформатекакb9.(Числуb в шестнадцатеричном коде соответствует 11 в десятичном.
Умножение 11 на 16 дает 176.Добавив9,получаемдесятичноезначение185.)В строке 12 установлен флаг showbase, что приводит к добавлению префикса 0x ко всемшестнадцатеричнымзначениям.В строке 16 ширина поля устанавливается равной 10. Поэтому выводимое значениесдвинуто вправо. В строке 20 ширина также устанавливается равной 10, однако применяетсявыравниваниевлево.Этотмоментхорошовиденввыводепрограммы.Встроке25ширинаостаетсяравной10,однакоприменяетсявыравниваниепоширинеполя.Поэтому0xвводитсяполевомукраюполя,аb9—поправому.Наконец, в строке 29 повторяются те же установки, но в этот раз функция setw()используетсяневотдельнойстроке,авпаресоператоромвывода(<<).Результатполучаетсятотже.Сравнениепотоковифункцииprintf()Большинство версий компиляторов C++ включают также стандартные библиотеки вводавывода языка С, позволяющие использовать для этого функцию printf(). Хотя использоватьprintf()немногопроще,чемcout,применятьеенежелательно.Функция printf() не обеспечивает должного контроля за типами данных, поэтому можнолегко ошибиться и отобразить число как символ или символ как число.
Кроме того, функцияprintf() не поддерживает классы, поэтому ее трудно использовать для вывода данных объектовклассов.Приходитсязадаватькаждыйчленклассадляpгintf()вотдельности.Сдругойстороны,этафункциязначительноупрощаетформатированиевыводимыхданных,так как позволяет вставлять спецификаторы форматирования в качестве параметров функции.Поскольку функция printf() все еще эффективно применяется в некоторых программах ипользуется популярностью у многих программистов, этот раздел посвятим краткому обзору ееиспользования.Для использования функции printf() необходимо включить в программу файл заголовкаstdio.h.
В самой простой форме функция printf() принимает в качестве параметра строку дляформатированного вывода в виде текста, взятого в кавычки. Перед строкой могут бытьустановленысамыеразличныенаборыспецификаторовформатирования.Втабл.16.1показанынаиболее часто используемые спецификаторы преобразований типов, начинающиеся всегда ссимвола%.Таблица16.1.СпецификаторыпреобразованиятиповКаждыйспецификаторпреобразованияможеттакжедополнятьсяустановкойобщегочислазнаков в выводимом значении и числа знаков после десятичной запятой. Эта установка имеетвид десятичного значения с плавающей точкой, где символы слева от точки устанавливаютобщее число знаков в выводимых значениях, а символы справа — число знаков после запятой.Например,спецификатор%5dзадаетвыводцелочисленногозначениядлиной5знаков,а%15.5f— вывод числа с плавающей запятой общей длиной в 15 знаков, пять из которых составляютдробнуючасть.Различныеспособыиспользованияprintf()показанывлистинге16.15.Листинг16.15.Выводданныхспомощьюфцнкцииprintf()1:#include<stdio.h>2:intmain()3:{4:printf("%s","helloworld\n");5:6:char*phrase="Helloagain!\n";7:printf("%s",phrase);8:9:intx=5;10:printf("%d\n",x);11:12:char*phraseTwo="Here'ssomevalues:";13:char*phraseThree="andalsothese:";14:intу=7,z=35;15:longlongVar=98456;16:floatfloatVar=8.8f;17:18:printf("%s%d%d%s%ld%f\n",phraseTwo,y,z,phraseThree,longVar,floatVar);19:20:char*phraseFour="Formatted:";21:printf("%s%5d%10d%10.5f\n",phraseFour,y,z,floatVar);22:return0;23:}Результат:helloworldHelloagain!5Here'ssomevalues:735andalsothese:984568.800000Formatted:7358.800000Анализ:Первыйразфункцияprintf()вызываетсявстроке4иимеетстандартнуюформу:заименем функции printf следует спецификатор преобразования (в данном случае %s) иконстантнаястрокавкавычках,выводимаянаэкран.Спецификатор%sуказывает,чтовданныймоментвыводитсятекстовая'строка,указаннаядалее,—"helloworld".Второй вызов функции printf в строке 7 аналогичен первому, но в данном случае вместоконстантнойстроки,заключеннойвкавычки,используетсяуказательтипаchar.В третьем вызове printf() в строке 10 используется спецификатор вывода целочисленногозначения, хранимого в переменной x.
Еще более сложным оказывается четвертый вариантвызова функции printf(), показанный в строке 18. Здесь выводится сразу шесть значений.Каждому приведенному спецификатору отвечает свое значение, отделенное от остальных спомощьюзапятых.Наконец, в строке 21 в уже хорошо известной вам функции printf() используютсяспецификаторыформатирования,определяющиедлинуиточностьвыводимыхзначений.Многиесчитают, что форматирование вывода данных с помощью спецификаторов функции printf()намногопроще,чемспомощьюманипуляторовобъектаcout.Ранее уже отмечались основные недостатки функции printf() — отсутствие строгогоконтроля за типами данных и невозможность объявления этой функции как друга или методакласса.
Поэтому при необходимости распечатать данные различных членов класса нужноиспользоватьявнозаданныеметодыдоступакчленамкласса.ОбобщениеметодовуправлениявыводомданныхвпрограммахнаC++Для форматирования вывода данных в C++ можно использовать комбинации специальныхсимволов,манипуляторовифлагов.Ввыраженияхсобъектомcoutиспользуютсяследующиеспециальныесимволы:\n—новаястрока;\r—возвраткаретки;\t—табуляция;\\—обратныйслеш;\ddd(числоввосьмеричномкоде)—символASCII;\a—звуковойсигнал(звонок).Примервыражениявыводастроки:cout<<"\aAnerroroccured\t"Указанное выражение не только выводит сообщение об ошибке на экран компьютера. ноподает предупреждающий звуковой сигнал и выполняет переход к следующей позициитабуляции.
С оператором cout используются также манипуляторы. Однако для использованиябольшинства манипуляторов нужно включить в программу файл iomanip.h. Далее вашемувниманиюпредставленсписокманипуляторов,нетребующихвключенияiomanip.h:flush—очищаетбуфервывода;endl—вставляетсимволразрывастрокииочищаетбуфервывода;oct—устанавливаетвосьмеричноеоснованиедлявыводимыхчисел;dec—устанавливаетдесятичноеоснованиедлявыводимыхчисел;hex—устанавливаетшестнадцатеричноеоснованиедлявыводимыхчисел.Атеперьприведемнаборманипуляторов,длякоторыхнеобходимовключениеiomanip.h:setbase(основание)—устанавливаетоснованиедлявыводимыхчисел(0=десятичная,8=восьмеричная,10=десятичная,16=шестнадцатеричная);setw(ширина)—устанавливаетминимальнуюширинуполявывода;setfill(символ)—устанавливаетсимволзаполнениянезанятыхпозицийполявывода;setprecision(точность)—устанавливаетчислознаковпослеплавающейзапятой;setiosflags(флаг)—устанавливаетодинилинесколькофлагов;resetiosflags(флаг)—сбрасываетодинилинесколькофлагов.Например,встрокеcout<<setw(12)<<setfill("#')<<hex<<x<<endl;устанавливается ширина поля в 12 знаков, символ заполнения #, восьмеричное основаниевыводимых чисел, после чего выводится значение переменной x, добавляется символ разрывастроки и очищается буфер.
Все манипуляторы, за исключением flush, endl и setw, остаютсявключенныминапротяжениивсейработыпрограммы,если,конечно,небудутсделаныдругиеустановки.Установкаманипулятораsetwотменяетсясразужепослетекущеговыводасобъектомcout.Сманипуляторамиsetiosflagsиresetiosflagsмогутиспользоватьсяследующиеювнфлаги:iоs::left—выравниваетданныеполевомукраюполявывода;ios::right—выравниваетданныепоправомукраюполявывода;ios::interval—выравниваетданныепоширинеполявывода;ios::dec—выводитданныевдесятичномформате;ios::oct—выводитданныеввосьмеричномформате;ios::hex—выводитданныевшестнадцатеричномформате;ios::showbase — добавляет префикс 0x к шестнадцатеричным значениям и О квосьмеричнымзначениям;ios::showpoint—заполняетнуляминедостающиезнакивзначенияхзаданнойдлины;ios::uppercase—отображаетвверхнемрегистрешестнадцатеричныеиэкспоненциальныезначения;ios::showpos—добавляетзнак'+'передположительнымичислами;ios::scientific — отображает числа с плавающей запятой в экспоненциальномпредставлении;ios::fixed—отображаетчисласплавающейзапятойвшестнадцатеричномпредставлении.Дополнительнуюинформациюможнополучитьизфайлаios.hилиизсправочнойсистемыкомпилятора.ИспользованиефайловдлявводаивыводаданныхПотоки C++ обеспечивают универсальные методы обработки данных, поступающих склавиатурыилидиска,атакжевыводимыхнаэкранидиск.Влюбомслучаеможноиспользоватьлибо операторы ввода и вывода, либо другие стандартные функции и манипуляторы.Дальнейшие разделы главы посвящены операциям открытия и закрытия файлов, которыесопровождаютсясозданиемобъектовifstreamиofstream.ОбъектыofstreamОбъекты,создаваемыедлясчитыванияилизаписиданныхвфайл,называютсяofstream.Ониявляютсяпроизводнымиотужезнакомоговамклассаiostream.Чтобыприступитькзаписивфайл,нужносначаласоздатьобъектofstream,азатемсвязатьего с определенным файлом на диске.