Ввод-вывод в файлы
Для чтения-записи в потоки можно использовать перегружаемые операторы-функции >> и <<. Например:
#include <fstream.h>//пример 61
int main(){
ofstream fout("test"); /* создание файла вывода c помощью конструктора */
if(!fout) { cout << "Файл открыть невозможно\n";
return 1; }
fout << "Привет!\n";
fout << 100 << ' ' << hex << 100 << endl;
fout.close();
ifstream fin("test"); // открытие обычного файла ввода
if(!fin) {cout << "Файл открыть невозможно\n";return 1;}
char str[80];
int i;
fin >> str >> i;
cout << str << ' ' << i << endl;
fin.close();
return 0; }
Сам оператор << можно перегрузить, как в следующем примере:
/*создание недружественной функции-вставки для объектов Coord */
#include <iostream.h>//пример 62
class Coord {
public:
int x,y;//должны быть открытыми
Coord() {x=0;y=0;}
Coord(int i,int j) {x=i;y=j;}
};
//функция вставки для объектов класса coord
ostream &operator<<(ostream &stream, Coord ob){
stream <<ob.x<<”,”<<ob.y<<’\n’;
return stream;
}
int main(){
Coord a(1,1), b(10,23);
cout <<a<<b;
return 0; }
Оператор ввода (извлечения) также можно перегрузить:
istream &operator>>(istream &stream, имя_класса ob){
//тело функций ввода
return stream;
}
При работе с файлами возможно использование методов ввода-вывода одного символа: istream &get(char &ch); и ostream &put(char ch);
Пример использования этих методов и аргументов командной строки:
#include <iostream.h>//пример 63
#include <fstream.h>
int main(int argc, char *argv[ ]) {
char ch;
if(argc!=2) {
cout << "Использование:WRITE<имя_файла>\n";
return 1;}
ofstream out(argv[1]);
if(!out) {cout << "Файл открыть невозможно\n";return 1; }
cout << "Для остановки введите символ $\n";
do {
cout << ": ";
cin.get(ch);
out.put(ch);
} while (ch!='$');
out.close();
return 0; }
Для записи-считывания блоков двоичных данных используются функции, которые считывают-записывают n байт в буфер или из буфера:
istream &read(unsigned char *buf, int n);
ostream &write(const unsigned char *buf, int n);
#include <iostream.h>//Пример 64
#include <fstream.h>
#include <string.h>
int main() {
ofstream out("test", ios::binary);/* не будет нежелательных проебразований символов при вводе и выводе*/
if(!out) {cout << "Файл открыть невозможно\n";return 1;}
double num = 100.45;
char str[ ] = "Это проверка";
out.write((char *) &num, sizeof(double));
out.write(str, strlen(str));
out.close();
return 0; }
Для позиционирования в файле имеются методы seekg(), seekp(), tellp(). При этом seekg() назначает или возвращает текущую позицию указателя чтения, а seekp() – текущую позицию указателя записи. Обе функции могут иметь один или два аргумента. При вызове с одним аргументом функции перемещают указатель на заданное место, а при вызове с двумя аргументами вычисляется относительная позиция от начала файла (ios::beg) текущей позиции (ios::cur) или от конца файла (ios::end). Текущая позиция определяется методом tellp().
Для объектов файловых потоков контроль состояния производится с помощью методов, манипулирующих флагами ошибок:
bad() – возвращает ненулевое значение, если обнаружена ошибка;
clear() – сбрасывает сообщения об ошибках;
eof() – возвращает ненулевое значение, если обнаружен конец файла;
fail() – возвращает ненулевое значение, если операция завершилась неудачно;
good() – возвращает ненулевое значение, если флаги ошибок не выставлены;
rdstate() – возвращает текущее состояние флагов ошибок.
Если флаги показывают наличие ошибки, все попытки поместить в поток новые объекты будут игнорироваться.