Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Все манипуляторные функции ввода данных без параметров имеют следующую структуру.
istream & manip_name(istream & stream) { // код манипуляторной функции return stream; } Например, в следующей программе создается манипулятор prompt(). Он настраивает входной поток на прием данных в шестнадцатеричном представлении и отображает для пользователя наводящее сообщение. #include < iostream> #include < iomanip> using namespace std; istream & prompt(istream & stream) { cin > > hex; cout < < " Введите число в шестнадцатеричном формате: "; return stream; } Int main() { int i; cin > > prompt > > i; cout < < i; return 0; } Помните: очень важно, чтобы ваш манипулятор возвращал потоковый объект (элемент stream). В противном случае этот манипулятор нельзя будет использовать в составном выражении ввода или вывода. Файловый ввод-вывод В С++-системе ввода-вывода также предусмотрены средства для выполнения соответствующих операций с использованием файлов. Файловые операции ввода-вывода можно реализовать после включения в программу заголовка < fstream> , в котором определены все необходимые для этого классы и значения. Как открыть и закрыть файл В C++ файл открывается путем связывания его с потоком. Как вы знаете, существуют потоки трех типов: ввода, вывода и ввода-вывода. Чтобы открыть входной поток, необходимо объявить потоковый объект типа ifstream. Для открытия выходного потока нужно объявить поток класса ofstream. Поток, который предполагается использовать для операций как ввода, так и вывода, должен быть объявлен как объект класса fstream. Например, при выполнении следующего фрагмента кода будет создан входной поток, выходной и поток, позволяющий выполнение операций в обоих направлениях. Ifstream in; // входной поток Ofstream out; // выходной поток Fstream both; // поток ввода-вывода Чтобы открыть файл, используйте функцию open(). Создав поток, его нужно связать с файлом. Это можно сделать с помощью функции open(), причем в каждом из трех потоковых классов есть своя функция-член open(). Представим их прототипы. void ifstream:: open(const char *filename, ios:: openmode mode = ios:: in); void ofstream:: open(const char *filename, ios:: openmode mode = ios:: out | ios:: trunc); void fstream:: open(const char * filename, ios:: openmode mode = ios:: in | ios:: out); Здесь элемент filename означает имя файла, которое может включать спецификатор пути. Элемент mode определяет способ открытия файла. Он должен принимать одно или несколько значений перечисления openmode, которое определено в классе ios. Ios:: арр Ios:: ate Ios:: rbinary Ios:: in Ios:: out Ios:: trunc Несколько значений перечисления openmode можно объединять посредством логического сложения (ИЛИ). На заметку. Параметр mode для функции fstream:: open() может не устанавливаться по умолчанию равным значению in | out (это зависит от используемого компилятора). Поэтому при необходимости этот параметр вам придется задавать в явном виде. Включение значения ios:: арр в параметр mode обеспечит присоединение к концу файла всех выводимых данных. Это значение можно применять только к файлам, открытым для вывода данных. При открытии файла с использованием значения ios:: ate поиск будет начинаться с конца файла. Несмотря на это, операции ввода-вывода могут по-прежнему выполняться по всему файлу. Значение ios:: in говорит о том, что данный файл открывается для ввода данных, а значение ios:: out обеспечивает открытие файла для вывода данных. Значение ios:: binary позволяет открыть файл в двоичном режиме. По умолчанию все файлы открываются в текстовом режиме. Как упоминалось выше, в текстовом режиме могут происходить некоторые преобразования символов (например, последовательность, состоящая из символов возврата каретки и перехода на новую строку, может быть преобразована в символ новой строки). При открытии файла в двоичном режиме никакого преобразования символов не выполняется. Следует иметь в виду, любой файл, содержащий форматированный текст или еще необработанные данные, можно открыть как в двоичном, так и в текстовом режиме. Единственное различие между этими режимами состоит в преобразовании (или нет) символов. Использование значения ios:: trunc приводит к разрушению содержимого файла, имя которого совпадает с параметром filename, а сам этот файл усекается до нулевой длины. При создании выходного потока типа ofstream любой существующий файл с именем filename автоматически усекается до нулевой длины. При выполнении следующего фрагмента кода открывается обычный выходной файл. ofstream out; out.open(" тест" ); Поскольку параметр mode функции open() по умолчанию устанавливается равным значению, соответствующему типу открываемого потока, в предыдущем примере вообще нет необходимости задавать его значение. Не открытый в результате неудачного выполнения функции open() поток при использовании в булевом выражении устанавливается равным значению ЛОЖЬ. Этот факт может служить для подтверждения успешного открытия файла, например, с помощью такой if-инструкции. if(! mystream) { cout < < " He удается открыть файл."; // обработка ошибки } Прежде чем делать попытку получения доступа к файлу, следует всегда проверять результат вызова функции open(). Можно также проверить факт успешного открытия файла с помощью функции is_open(), которая является членом классов fstream, ifstream и ofstream. Вот ее прототип, bool is_open(); Эта функция возвращает значение ИСТИНА, если поток связан с открытым файлом, и ЛОЖЬ — в противном случае. Например, используя следующий код, можно узнать, открыт ли в данный момент потоковый объект mystream. if(! mystream.is_open()) { cout < < " Файл не открыт."; //... } Хотя вполне корректно использовать функцию open() для открытия файла, в большинстве случаев это делается по-другому, поскольку классы ifstream, ofstream и fstream включают конструкторы, которые автоматически открывают заданный файл. Параметры у этих конструкторов и их значения (действующие по умолчанию) совпадают с параметрами и соответствующими значениями функции open(). Поэтому чаще всего файл открывается так, как показано в следующем примере, ifstream mystream(" myfile" ); // файл открывается для ввода Если по какой-то причине файл открыть невозможно, потоковая переменная, связываемая с этим файлом, устанавливается равной значению ЛОЖЬ. Чтобы закрыть файл, вызовите функцию close(). Чтобы закрыть файл, используйте функцию-член close(). Например, чтобы закрыть файл, связанный с потоковым объектом mystream, используйте такую инструкцию, mystream.close(); Функция close() не имеет параметров и не возвращает никакого значения. Чтение и запись текстовых файлов Проще всего считывать данные из текстового файла или записывать их в него с помощью операторов " < < " и " > > " . Например, в следующей программе выполняется запись в файл test целого числа, значения с плавающей точкой и строки. // Запись данных в файл. #include < iostream> #include < fstream> using namespace std; Int main() { ofstream out(" test" ); if(! out) { cout < < " He удается открыть файл."; return 1; } out < < 10 < < " " < < 123.23 < < " "; out < < " Это короткий текстовый файл."; out.close(); return 0; } Следующая программа считывает целое число, float-значение, символ и строку из файла, созданного при выполнении предыдущей программой. // Считывание данных из файла. #include < iostream> #include < fstream> using namespace std; Int main() { char ch; int i; float f; char str[80]; ifstream in(" test" ); if(! in) { cout < < " He удается открыть файл."; return 1; } in > > i; in > > f; in > > ch; in > > str; cout < < i < < " " < < f < < " " < < ch < < " "; cout < < str; in.close(); return 0; } Следует иметь в виду, что при использовании оператора " > > " для считывания данных из текстовых файлов происходит преобразование некоторых символов. Например, " пробельные" символы опускаются. Если необходимо предотвратить какие бы то ни было преобразования символов, откройте файл в двоичном режиме доступа. Кроме того, помните, что при использовании оператора " > > " для считывания строки ввод прекращается при обнаружении первого " пробельного" символа. Неформатированный ввод-вывод данных в двоичном режиме Форматированные текстовые файлы (подобные тем, которые использовались в предыдущих примерах) полезны во многих ситуациях, но они не обладают гибкостью неформатированных двоичных файлов. Поэтому C++ поддерживает ряд функций файлового ввода-вывода в двоичном режиме, которые могут выполнять операции без форматирования данных. Для выполнения двоичных операций файлового ввода-вывода необходимо открыть файл с использованием спецификатора режима ios:: binary. Необходимо отметить, что функции обработки неформатированных файлов могут работать с файлами, открытыми в текстовом режиме доступа, но при этом могут иметь место преобразования символов, которые сводят на нет основную цель выполнения двоичных файловых операций. Функция get() считывает символ из файла, а функция put() записывает символ в файл. В общем случае существует два способа записи неформатированных двоичных данных в файл и считывания их из файла. Первый состоит в использовании функции-члена put() (для записи байта в файл) и функции-члена get() (для считывания байта из файла). Второй способ предполагает применение " блочных" С++-функций ввода-вывода read() и write(). Рассмотрим каждый способ в отдельности. Использование функций get() и put() Функции get() и put() имеют множество форматов, но чаще всего используются следующие их версии: istream & get(char & ch); ostream & put(char ch); Функция get() считывает один символ из соответствующего потока и помещает его значение в переменную ch. Она возвращает ссылку на поток, связанный с предварительно открытым файлом. При достижении конца этого файла значение ссылки станет равным нулю. Функция put() записывает символ ch в поток и возвращает ссылку на этот поток. При выполнении следующей программы на экран будет выведено содержимое любого заданного файла. Здесь используется функция get(). /* Отображение содержимого файла с помощью функции get(). */ #include < iostream> #include < fstream> using namespace std; int main(int argc, char *argv[]) { char ch; if(argc! =2) { cout < < " Применение: имя_программы < имя_файла> "; return 1; } ifstream in(argv[1], ios:: in | ios:: binary); if(! in) { cout < < " He удается открыть файл."; return 1; } while(in) { /* При достижении конца файла потоковый объект in примет значение false. */ in.get(ch); if(in) cout < < ch; } in.close(); return 0; } При достижении конца файла потоковый объект in примет значение ЛОЖЬ, которое остановит выполнение цикла while. Существует более короткий вариант цикла, предназначенного для считывания и отображения содержимого файла. while(in.get(ch)) cout < < ch; Этот вариант также имеет право на существование, поскольку функция get() возвращает потоковый объект in, который при достижении конца файла примет значение false. В следующей программе для записи строки в файл используется функция put(). /* Использование функции put() для записи строки в файл. */ #include < iostream> #include < fstream> using namespace std; Int main() { char *p = " Всем привет! "; ofstream out(" test", ios:: out | ios:: binary); if(! out) { cout < < " He удается открыть файл."; return 1; } while(*p) out.put(*p++); out.close(); return 0; } Считывание и запись в файл блоков данных Чтобы считывать и записывать в файл блоки двоичных данных, используйте функции-члены read() и write(). Их прототипы имеют следующий вид. istream & read(char *buf, streamsize num); ostream & write(const char *buf, int streamsize num); Функция read() считывает num байт данных из связанного с файлом потока и помещает их в буфер, адресуемый параметром buf. Функция write() записывает num байт данных в связанный с файлом поток из буфера, адресуемого параметром buf. Как упоминалось выше, тип streamsize определен как некоторая разновидность целочисленного типа. Он позволяет хранить самое большое количество байтов, которое может быть передано в процессе любой операции ввода-вывода. Функция read() вводит блок данных, а функция write() выводит его. Популярное:
|
Последнее изменение этой страницы: 2016-03-17; Просмотров: 1328; Нарушение авторского права страницы