Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Листинг 8.3
#include < fstream.h> #include < stdio.h>
int main() { setlocale(LC_ALL, " Russian"); ifstream fin(" text.txt", ios:: in|ios:: nocreate); if (! fin) { cout < < " Ошибка открытия файла." < < endl; return 1; }
fin.seekg(0, ios:: end); //1 long len = fin.tellg(); //2 char *buf = new char[len + 1]; //3 fin.seekg(0, ios:: beg); //4 fin.read(buf. len); //5 buf[len] = '\0'; long n = 0, i = 0, j = 0; //6 while(buf[i]) //7 { if(buf[i] = '? ') //8 { for(j = n; j < = i; j++) cout< < buf[j]; n = i + j; } if(buf[i] == '.'||buf[i] == '! ') n = i + j; i++; } fin.close(); //9 cout < < endl;
return 0; }
Для определения длины файла используются методы seekg и tel I g класса stream. С любым файлом при его открытии связывается так называемая текущая позиция чтения или записи. Когда файл открывается для чтения, эта позиция устанавливается на начало файла. Для определения длины файла мы перемещаем ее на конец файла с помощью метода seekg (оператор 1), а затем с помощью tel I g получаем ее значение, запомнив его в переменной 1 en (оператор 2). Метод seekg(offset, org) перемещает текущую позицию чтения из файла на offset байтов относительно org. Параметр org может принимать одно из трех значений: ios:: beg - от начала файла; i os:: cur - от текущей позиции; i os:: end - от конца файла. beg, cur и end являются константами, определенными в классе 1 os, предке 1 f stream, а символы:: означают операцию доступа к этому классу. В операторе 3 выделяется 1 en + -1 байтов под символьную строку buf, в которой будет храниться текст из файла. Мы выделяем на один байт больше, чем длина файла, чтобы после считывания файла записать в этот байт нуль-символ. Для чтения информации требуется снова переместить текущую позицию на начало файла (оператор 4). Собственно чтение выполняется в операторе 5 с помощью метода read(buf, I en), который считывает из файла Ten символов (или менее, если конец файла встретится раньше) в символьный массив buf. В операторе 6 определяются служебные переменные. В переменной п будет храниться позиция начала текущего предложения, переменная i используется для просмотра массива, переменная j - для вывода предложения. Цикл просмотра массива buf (оператор 7) завершается, когда встретился нуль-символ. Если очередным символом оказался вопросительный знак (оператор 8), выполняется вывод символов, начиная с позиции п до текущей, после чего в переменную п заносится позиция начала нового предложения. Оператор 9 (закрытие потока) в данном случае не является обязательным, так как явный вызов cl ose () необходим только тогда, когда требуется закрыть поток раньше окончания действия его области видимости. Если требуется вывести результаты выполнения программы не на экран, а в файл, в программе следует описать объект класса выходных потоков ofstream, а затем использовать его аналогично другим потоковым объектам, например:
ofstream fout(" textout.txt"); if(! fout) { cout < < " Ошибка открытия файла вывода" < < endl; return 1; } ... fout < < buf[j];
требуется закрыть поток раньше окончания действия:
fout.closeO;
чтение из файла. При использовании потоков оно выполняется с помощью метода get(). Например, для программы, приведенной выше, посимвольный ввод выглядит следующим образом:
while((buf[i] = fin.get())! = EOF { ... i++; }
Надо учитывать, что посимвольное чтение из файла гораздо менее эффективно. В заключение приведем вариант решения этой же задачи с использованием вместо потоковых классов библиотечных функций, унаследованных из языка С.
|