Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык программирования Сpp 25.09.11 (2).doc
Скачиваний:
16
Добавлен:
19.08.2019
Размер:
10.09 Mб
Скачать

If(!out){ //при неудачной попытке

ShowMessage("Не удалось создать выходной поток");

return;

}

else{//создание потока произошло

char *str=Edit1->Text.c_str();//преобразование строк

for(int i=0; i<(Edit1->Text).Length(); i++)

out<<str[i];//пересылка на диск

out.close();//закрытие потока

}

}

Исполнение обработчика начинается с выполнения кода записанного внутри круглыз скобок оператора if().

После выбора имени файла оно переписывается в строку MyFile. Если по каким то причинам попытка оказалаь неудачной, появляется сообщение "Невозможно открыть файл " с указанием имени файла.

Если диалог прошел удачно, то вызывается конструктор выходного потока, суказанием имени файла, в который будут записываться данные. Если в силу каких то причин поток не улалось создать, то пользователь получит сообщение "Не удалось создать выходной поток". Если поток создан, то элементы массива по очереди передаются в файл.

void __fastcall TForm1::OpenClick(TObject *Sender)

{

if(SaveDialog1->Execute())

MyFile=SaveDialog1->FileName;

else{

ShowMessage("Не удается открыть файл "+MyFile);

return;

}

ifstream in;

in.open(MyFile.c_str());

If(in.Fail()){ //поток не создан, то сообщение и выход

ShowMessage("Не удается создать файл "+MyFile);

return;

}

else{ //если поток создан

int i=0;

char str[100];

in>>str[0];

while(str[i]!=EOF){//Пока не будет достигнут коней файла

i++ ;

in>>str[i];

}

Edit2->Text=AnsiString(str); //Преобразование строк

in.close();

}

}

Как и в предыдущем случае исполнение обработчика начинается с выполнения кода записанного внутри круглыз скобок оператора if(). При удачном открытии файла создается входной поток. В данном случае он создается с помощью конструктора без параметров. Это сделано для того, чтобы проиллюстрировать иной способ создания потока. Функция fail() возвращает значение true, если поток удалось создать. Ввиду того, что размер файла заранее неизвестен приходится созать массив размер которого будет больше, чем размер файла, в данном случае это str[100]. После того как массив заполнен, о чем свидетельствует возвращение потоком признака конца файла EOF, строка переводится в тип AnsiString и выводится в Edit2.

Обработчик выхода из программы вообще выглядит очень просто

void __fastcall TForm1::ExitClick(TObject *Sender)

{

exit(0);

}

В данном примере выходной поток стирает в файле записанные ранее данные.

Если в левом окне написать несколько слов через пробел и записать их в файл, то то в правом окне в считанной строке будут отсутствоваьь пробелы.

Это связано с тем, что операция взятия из потока (>>) читает не всю строку, а только одну лексему, т.е. последовательность символов между двумя пробелами.

Дополнительно о классе ofstream

Конструктор класса ofstream перегружен. Наиболее полныей вид:

ofstream(const char* szName,

int nMode = ios::out,

int nProt = filebuf::openprot);

Первый аргумент – имя выходного файла, и это единственный обязательный аргумент. Второй аргумент задает режим, в котором открывается поток. Этот аргумент – логическое ИЛИ из следующих величин:

ios::app

при записи данные добавляются в конец файла, даже если текущая позиция была перед этим перемещена;

ios::ate

при создании потока текущая позиция помещается в конец файла; однако, в отличие от режима app, запись ведется в текущую позицию;

ios::in

поток создается для ввода; если файл уже существует, он сохраняется;

ios::out

поток создается для вывода (режим по умолчанию);

ios::trunc

если файл уже существует, его прежнее содержимое уничтожается, и длина файла становится равной нулю; режим действует по умолчанию, если не заданы ios::ate, ios::app или ios::in;

ios::binary

ввод-вывод будет происходить в двоичном виде, по умолчанию используется текстовое представление данных.

Третий аргумент используется только в том случае, если создается новый файл; он определяет параметры создаваемого файла.

Можно создать поток вывода с помощью стандартного конструктора без аргументов, а позднее выполнить метод open с такими же аргументами, как у предыдущего конструктора:

void open(const char* szName,

int nMode = ios::out,

int nProt = filebuf::openprot);

Только после того, как поток создан и соединен с определенным файлом (либо с помощью конструктора с аргументами, либо с помощью метода open), можно выполнять вывод. Выводятся данные операцией <<. Кроме того, данные можно вывести с помощью методов write или put:

ostream& write(const char* pch,

int nCount);

ostream& put(char ch);

Метод write выводит указанное количество байтов (nCount), расположенных в памяти, начиная с адреса pch. Метод put выводит один байт.

Например, если имеется поток с именем fout ,оператор

fout.put(‘Z’);

выведет в поток символ «Z».

Функции put() допускают сцепление, например

fout.put(‘Z’).put(‘\n’);

В данном случае в поток попадет сивол «Z», а за ним перевод на новую строку.

Для того чтобы переместить текущую позицию, используется метод seekp:

ostream& seekp(streamoff off,

ios::seek_dir dir);

Первый аргумент – целое число, смещение позиции в байтах. Второй аргумент определяет, откуда отсчитывается смещение; он может принимать одно из трех значений:

ios::beg

смещение от начала файла

ios::cur

смещение от текущей позиции

ios::end

смещение от конца файла


Сместив текущую позицию, операции вывода продолжаются с нового места файла.

После завершения вывода можно выполнить метод close, который выводит внутренние буферы в файл и отсоединяет поток от файла. То же самое происходит и при уничтожении объекта.

Пример.

char s[80], c;

ifstream infile("test.txt");

if(!infile){

ShowMessage("Файл не удается открыть");

return;

}

int i=0;

while((c=infile.get())!=EOF){

if(c=='\n')

//занесение нулевого символа в конец строки

s[i]=0;

// обработка строки

. . .

i=0;

}

//формирование строки

else s[i++]=c;

}

//закрытие файла

infile.close();

Дополнительно о классе ifstream

Класс ifstream, осуществляющий ввод из файлов, работает аналогично. При создании объекта типа ifstream в качестве аргумента конструктора можно задать имя существующего файла:

ifstream(const char* szName, int nMode = ios::in,

int nProt = filebuf::openprot);

Можно воспользоваться стандартным конструктором, а подсоединиться к файлу с помощью метода open.

В классе ifstream есть методы чтения из потока.

Метод write() выводит в файл из символьного массива на который указывает его первый параметр число символов заданных вторым параметром. Например,

out.write(str,5);

записывае в поток out 5 символов из массива str. Символы не обрабатываются. Это значит, что если встречаются управляющие символы, например, символ конца строки ’\0’, то он рассматривается просто как символ.

В классе ifstream есть методы чтения из потока.

Метод read(), предназначен для чтения из потока без обработки.

Функция gcount() сообщает количество символов, прочитанных последней операцией ввода.

Метод get() имеет три модификации:

get()

Возвращает одиночный символ без анализа.

get(char)

Возвращает ссылку на на тот объект потока. для которого вызывался метод

get(char*, int n, char delim)

Примеры.

char s[80], c;

ifstream infile("test.txt");

if(!infile){

ShowMessage("Файл не удается открыть");

return;

}

int i=0;

while((c=infile.get())!=EOF){

if(c=='\n')

//занесение нулевого символа в конец строки

s[i]=0;

// обработка строки

. . .

i=0;

}

//формирование строки

else s[i++]=c;

}

//закрытие файла

infile.close();