Г. Шилтд - Самоучитель C++ (PDF) (1114887), страница 41
Текст из файла (страница 41)
То есть,как правило, файлы с отформатированным текстом, которые вы будете обрабатывать, используя операторы « и », следует открывать в текстовом, ане в двоичном режиме. Двоичный режим больше подходит для неотформатированных файлов, о которых в этой главе будет рассказано позже.Примеры1. В представленной ниже программе создается файл для вывода, туда записывается информация, и файл закрывается. Затем файл снова открывается уже вкачестве файла для ввода, и записанная ранее информация оттуда считывается:tfinclude <iostream>#include <fstream>using namespace std;intmain()ofstream fout("test"); // создание файла для выводаif{!font) {cout « "Файл открыть невозможно\п";return 1;fout « "Привет !\п";fout « 100 « ' ' « hex « 100 « endl;fout .close () ;if stream fin ("test"); // открытие файла для вводаif П fin) {cout « "Файл открыть невозможно\п";return 1;char str[80] ;int i;fin » str » i;cout « str « ' ' « i « endl;fin.
close () ;return 0;.280_______Самоучитель C++После того как программа завершится, проанализируйте содержимое файлаtest. Оно будет следующим:Привет !100 64Как уже установлено, при использовании операторов « и » для реализации файлового ввода/вывода, информация форматируется так же, как еслибы она находилась на экране.2. Рассмотрим другой пример файлового ввода/вывода. В этой программе введенные с клавиатуры строки считываются и записываются в файл. Программа завершается при вводе знака доллара $ в качестве первого символастроки.
Для использования программы в командной строке задайте имя файла для вывода.ftinclude <iostream>^include <fstream>using namespace std;int main{int argc,char * a r g v [ ] ){if(argc!=2) {cout « "Введите <имя_файла>\п" ;return 1;ofstream out (argv[l] ) ; // файл для. выводаif (lout) {cout « "Файл открыть невозможной";return 1 ;char str[80] ;cout « "Вводите строки; для окончания ввода введите S\n";do {cout « ": ";cin » str;out « str « endl;} while (*str != 'S1) ;out. close () ;return 0;3.
В следующей программе копируется текстовый файл и при этом пробелыпревращаются в символы [. Обратите внимание, как для контроля концафайла для ввода используется функция eof(). Также обратите внимание, какГлава 9. Дополнительные возможности ввода/вывода в C++28?поток ввода fin воспринимает сброс флага skipws. Это предотвращает пропускпробелов в начале строк.// Превращение пробелов в вертикальные линии |ftinclude <iostrearn>ttinclude <fstream>using namespace std;int main(int argc,char * a r g v [ ] )if (argc!=3) {cout « "Преобразование <файл_ввода> <файл_вывода>\п";return 1 ;}ifstream fin(argv[l] ) ; // открытие файла для вводаofstream fout (argv[2] ) ; // создание файла для выводаif (lout) {cout « "Файл открыть невозможной";return 1;}if(!fin) {cout « "Файл открыть невозможно\п" ;return 1;}char ch;f in.
unsetf (ios: : skipws) ; // не пропускать пробелыwhile ( ! f i n , eof ( ) ) {fin » ch;if (ch==' ') ch = ' | ';if ( ! f i n . eof () ) fout « ch;fin. close () ;fout. close () ;return 0;4. Между исходной библиотекой ввода/вывода C++ и библиотекой ввода/вывода современного стандарта Standard C++ имеются некоторые отличия, которые необходимо учитывать при модернизации старых программ.Во-первых, в исходной библиотеке ввода/вывода C++ у функции ореп(') имеется третий параметр, задающий режим защиты файла.
По умолчанию эторежим обычного файла. В современной библиотеке C++ указанный параметр не поддерживается.Во-вторых, при работе со старой библиотекой для открытия потока ввода/вывода fstream необходимо явно указать значения режима открытия файла282Самоучитель C++ios::in и ios::out. Значения режима открытия файла по умолчанию не поддерживаются. Это относится как к конструктору класса fstream, так и к функцииорел(). Например, при работе со старой библиотекой ввода/вывода C++,чтобы открыть файл для ввода и вывода с помощью функции ореп(), необходимо использовать следующую конструкцию:fstream mystream;mystream.openC'test", i o s : : i n j i o s : : o u t ) ;В современной библиотеке ввода/вывода C++, если режим открытия файлане указан, любой объект типа fstream автоматически открывает файл дляввода и вывода.И последнее. При работе со старой библиотекой ввода/вывода к ошибке выполнения функции openQ ведет значение режима открытия файла, равноеios::noncreate, если указанный файл не существует, или равное ios::noreplace,если, наоборот, указанный файл уже существует.
В стандарте Standard C++данные значения режима открытия файла не поддерживаются.1. Напишите программу для копирования текстового файла. Эта программадолжна подсчитывать число копируемых символов и выводить на экран полученный результат. Почему это число отличается от того, которое выводится при просмотре списка файлов каталога?2. Напишите программу для заполнения информацией следующей таблицы вфайле phone.Исаак Ньютон, 415 555-3423Роберт Годдард, 213 555-2312Энрико Ферми, 202 555-11113.
Напишите программу для подсчета числа слов в файле. Для простоты считайте, что словом является все, имеющее с двух сторон пробелы.4. Какие действия выполняет функция is_open?9.3. Неформатируемый двоичныйввод/выводХотя текстовые файлы (т. е. файлы, информация в которых представленав кодах ASCII, — примеч. пер.) полезны во многих ситуациях, у них нет гибкости неформатированных двоичных файлов. Неформатированные файлысодержат те самые исходные или "сырые" двоичные данные, которые непосредственно используются вашей программой, а не удобный для восприятияГлава 9. Дополнительные возможности ввода/вывода в C++283человека текст, данные для которого транслируются операторами « и ».Поэтому о неформатируемом вводе/выводе иногда говорят как о "сыром"(raw) вводе/выводе.
В C++ для двоичных файлов поддерживается широкийдиапазон функций ввода/вывода. Эти функции дают возможность точноконтролировать процессы считывания из файлов и записи в файлы.На нижнем уровне двоичного ввода/вывода находятся функции get() и put().С помощью функции-члена put() можно записать байт; а с помощью функции-члена get() — считать. Эти функции являются членами всех потоковыхклассов соответственно для ввода и для вывода. Функции get() и put() имеют множество форм. Ниже приведены их наиболее часто встречающиесяверсии:istream figet(char £ символ) ;ostream &put(char символ);Функция get() считывает один символ из связанного с ней потока и передает его значение аргументу символ. Ее возвращаемым значением являетсяссылка на поток.
При считывании символа конца файла функция возвратитвызывающему потоку значение false. Функция put() записывает символ впоток и возвращает ссылку на поток.Для считывания и записи блоков двоичных данных используются функцииread() и writeQ, которые также являются членами потоковых классов соответственно для ввода и для вывода. Здесь показаны их прототипы:istream firead(char * буфер, streamsize число_байгг) ;ostreamfiwrite(constchar * буфер,streamsize чксло_байт);Функция readQ считывает из вызывающего потока столько байтов, сколькозадано в аргументе число_6айт и передает их в буфер, определенный указателем буфер.
Функция write() записывает в соответствующий поток из буфера, который определен указателем буфер, заданное в аргументе число_байтчисло байтов. Значения типа streamsize представляют собой некоторуюформу целого.Если конец файла достигнут до того, как было считано число_байт символов, выполнение функции read() просто прекращается, а в буфере оказывается столько символов, сколько их было в файле. Узнать, сколько символовбыло считано, можно с помощью другой функции-члена gcount(), прототипкоторой приведен ниже:streamsize gcountO ;Функция возвращает количество символов, считанных во время последнейоперации двоичного ввода.Естественно, что при использовании функций, предназначенных для работыс двоичными файлами, файлы обычно открывают в двоичном, а не в тек-284Самоучитель C++стовом режиме.
Смысл этого понять легко, значение режима открытия файла ios::binary предотвращает какое бы то ни было преобразование символов.Это важно, когда в файле хранятся двоичные данные, например, целые, вещественные или указатели. Тем не менее, для файла, открытого в текстовомрежиме, хотя в нем содержится только текст, двоичные функции такжевполне доступны, но при этом помните о возможности нежелательного преобразования символов.1. В следующей программе на экран выводится содержимое файла. Используется функция get().^include <iostream>ttinclude <fstream>using namespace std;int main(int argc,*char * a r g v [ ] )char ch;if(argc!=2){cout « "Содержимое: <имя_файла>\п";return 1;ifstream in(argv[lj, ios::in | ios : :binary) ;i£(!in) {cout « "Файл открыть невозможно\п";return 1 ;while ( ! in,eof () )in.
get (ch) ;cout « ch;in. close (} ;return 0;2. В данной программе для записи в файл вводимых пользователем символовиспользуется функция put(). Программа завершается при вводе знака доллара $.#include <iostream>#include <fstream>using namespace std;Глава 9. Дополнительные возможности ввода/вывода в C++285in.t main(int argc, char *argv[]}char ch;if(argc!=2){cout « "Запись: <имя файла>\п";return 1;ofstream out[argv[l], ios::out I ios:ibinary);if (lout) {cout « "Файл открыть невозможноХп";return 1;cout « "Для остановки введите символ $\п";do {cout « ": ";cin.get(ch);out.put(ch);} while (ch!='$') ;out.close ();return 0;Обратите внимание, что для считывания символов из потока cin в программеиспользуется функция get().