|
Программирование >> Процедурные приложения
пропустить. Символ звездочки (*) указывает на то, что данные должны быть прочитаны, но не сохранены. Отметим два важных момента. Если после строки ps1 первой встретится буква, а не дефис, выполнение функции scanf() завершится ошибкой, в переменную ps2 ничего не будет записано, а сама строка останется в буфере потока. Если бы в первой управляющей последовательности символ дефиса не был отмечен как пропускаемый, функция scanf() работала бы неправильно, так как символ дефиса, являющийся ограничителем строки ps1, воспринимался бы как часть этой строки! В этом случае чтение было бы прекращено только после обнаружения буквы, а это, в свою очередь, привело бы к возникновению ошибки, описанной в первом пункте. Последняя управляющая последовательность %[\ ] указывает на то, что в строку ps2 нужно считывать все символы, кроме двойных кавычек, которые являются признаком завершения ввода. Для полной ясности приведем пример входной строки: 65 - -ААА Вот что будет получено в результате: *psl= 65, *ps2 = ааа. Все вышесказанное справедливо и в отношении функций fscanf () и sscanf (). Функция sscanf() работает точно так же, как и scanf(),но читает данные из указанного символьного массива, а не из потока stdin. В следующем примере показано, как с помощью функции sscanf() преобразовать строку цифр в целое число: sscanf(psz, %d ,&ivalue); Глава 11. Основы ввода-вывода в языке C++ Подсистема ввода-вывода в C++ o Стандартные потоки cin , cout и сеrr o Операторы ввода (>>) и вывода (<<) данных Флаги и функции форматирования Файловый ввод-вывод Определение состояния потока Хотя в целом C++ является расширенной версией языка С, это не означает, что для создания эффективной программы достаточно взять каждое выражение на С и записать его синтаксический эквивалент на C++. Очень часто C++ предлагает не только дополнительные операторы, но и новые способы решения традиционных задач. Одним из новшеств языка является уникальная подсистема ввода-вывода, знакомство с которой мы начнем в этой главе, а завершим в главе 15. Разделение данной темы на две главы необходимо из-за разнообразия средств ввода-вывода, используемых в C++, что связано с внедрением в язык концепции объектно-ориентированного прoграммирования. Только после того, как вы уясните принципы создания объектов и манипулирования ими, вы сможете в полной мере освоить новую методику ввода-вывода данных посредством объектов. Пока же вам следует быть готовыми к тому, что некоторые термины и понятия, упоминаемые в настоящей главе, могут оказаться для вас незнакомыми. Подсистема ввода-вывода в C++ Стандартные функции ввода-вывода, используемые в языке С и объявленные в файле STDIO.H, доступны также и в C++. В то же время C++ располагает своим собственным файлом заголовков IOSTREAM.H, содержащим набор средств ввода-вывода, специфичных для этого языка. Потоковый ввод-вывод в C++ организуется посредством комплекта стандартных классов, подключаемых с помощью файла IOSTREAM.H. Эти классы содержат перегруженные операторы ввода >> и вывода <<, которые поддерживают работу с данными всевозможных типов. Чтобы лучше понять, почему легче работать с потоками в C++, чём в С, давайте вспомним, как вообще в языке С реализуется ввод и вывод данных. Прежде всего вспомним о том, что язык С не имеет встроенных средств ввода-вывода. Все функции, такие как printf() или scanf(), предоставляются через внешние библиотеки, хоть и считающиеся стандартными, но не являющиеся частью самого языка. В принципе, это позволяет гибко решать проблемы, возникающие в различных приложениях, в соответствии с их особенностями и назначением. Трудности появляются в связи с тем, что подобного рода функций слишком много, они по-разному возвращают значения и принимают разные аргументы. Программисты полагаются главным образом на функции форматного ввода-вывода, printf(), scanf() и им подобные, особенно если приходится работать с числами, а не текстом. Эти функции достаточно универсальны, но зачастую, из-за обилия всевозможных спецификаторов форматирования, становятся чересчур громоздкими и трудно читаемыми. Язык C++ точно так же не располагает встроенными средствами ввода-вывода, но предлагает модульный подход к решению данной проблемы, группируя возможности ввода-вывода в трех основных потоковых классах: istream содержит средства ввода ostream содержит средства вывода iostream поддерживает двунаправленный ввод-вывод, является производным от первых двух классов Во всех этих классах реализованы операторы << и >>, оптимизированные для работы с конкретными данными. Библиотека IOSTREAM.H содержит также классы, с помощью которых можно управлять вводом-выводом данных из файлов: ifstream Порожден от istreamи подключает к программе файл, предназначенный для ввода данных ofstream Порожден от ostream и подключает к программе файл, предназначенный для вывода данных fstream Порожден от iostream и подключает к программе файл, предназначенный как для ввода, так и для вывода данных Стандартные потоки cin, coutи cerr Стандартным потокам языка С stdin, stdoutи stderr, объявленным в файле STDIO.H, в C++ соответствуют объекты-потоки cin, cout, cerrи clog, подключаемые посредством файла IOSTREAM.H. cin Объект класса istream, связанный со стандартным потоком ввода cout Объект класса ostream, связанный со стандартным потоком вывода cerr Объект класса ostream, не поддерживающий буферизацию и связанный со стандартным потоком ошибок clog Объект класса ostream, поддерживающий буферизацию и связанный со стандартным потоком ошибок Все они открываются автоматически во время запуска программы и обеспечивают интерфейс между программой и пользователем. Операторы ввода (>>) и вывода (<<) данных Ввод-вывод в C++ значительно усовершенствован и упрощен благодаря универсальным операторам >> (ввод) и << (вывод). Их универсальность стала возможной благодаря появившемуся в C++ понятию перегрузки операторов, которая заключается в создании функций, имена которых совпадают с именами стандартных операторов языка. Компилятор различает вызов настоящего и функционального операторов на основании типов передаваемых им операндов. Операторы >> и << перегружены таким образом, чтобы поддерживать все стандартные типы данных C++, включая классы. Рассмотрим пример вывода данных с помощью функции printf() в языке С: printf( Целое числей./%d число с плавающей запятой: %f ,ivalue, fvalue); А теперь запишем это же выражение на C++: cout<< Целое число: << ivalue<< , число с плавающей запятой: << fvalue; Обратите внимание, что один и тот же перегруженный оператор используется для вывода данных трех разных типов: строк, целых чисел и чисел с плавающей запятой. Оператор << самостоятельно проанализирует тип данных и выберет подходящий формат их представления. Аналогично работает оператор ввода. Сравним два эквивалентных выражения на языках С и C++: /* на языке С */ scanf( %d%f%c ,&ivalue, &fvalue, &c); на языке С+.+ cin >> ivalue >> fvalue >> c; Нет необходимости при вводе данных ставить перед именами переменных оператор взятия адреса &. В C++ оператор >> берет на себя задачу вычисления адреса, определения формата и прочих особенностей записи значения переменной. Прямым следствием перегрузки является возможность расширения операторов << и>> для обработки данных нестандартных типов. Ниже показано, как перегрузить оператор вывода, чтобы он мог принимать данные нового типа tclient: ostream& operator (ostream& osout, tclient client) osout<< << client.pszname; osout<< << client.pszaddress;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |