Работа с файлами в С++ ­Чтение и запись в файл значения переменной ­ Чтение и запись в файл значений элементов массивов © Чирюкина, 2007 Файлы и каталоги на дисках • Каждый файл можно найти по его имени; • Имя файла может быть абсолютным и относительным; – Абсолютное имя файла прописывается от корня диска, на котором расположен файл; – Относительное имя файла прописывается относительно активной директории. Примеры абсолютных имен файлов • C:\my.pas – файл my.pas находится в корневом каталоге диска С; • C:\work\my.pas – на диске С есть папка work, и в ней находится файл my.pas; • C:\work\student\my.pas – на диске С есть папка work, в неё вложена папка student, и уже в этой вложенной папке находится файл my.pas. Примеры относительных имен файлов • • • my.pas – в рабочей директории находится файл my.pas (рис. 1); ..\ my.pas – в наддиректории текущей директории находится файл my.pas (рис. 2); ..\student \my.pas – в наддиректории текущей директории есть папка student, и в этой папке находится файл my.pas (рис.3). C: C: C: SomeDirectory SomeDirectory ActiveDirectory ­ my.pas AnotherDirectory Рис. 1. ActiveDirectory SomeDirectory ­ my.pas Student ­ my.pas ActiveDirectory AnotherDirectory Рис. 2. AnotherDirectory Рис. 3. Как получить доступ к файлу из программы Программа Жесткий диск Файл на жестком Шаг 1. Создать ассоциацию между диске файловой переменной в программе и Text.txt файлом на жестком диске компьютера и открыть файл в одном из режимов: •Для чтения и перезаписи; •Для дозаписи. Файловая переменная ofstream fout; ­ для записи ifstream fout; ­ для чтения fout.open(‘history.txt’); fout.open("history.txt",ios::app); Шаг 2. Оперирование с данными (зависит от режима, в котором открыт файл): Чтение данных; Запись данных. Шаг 3. Закрытие файла. Примеры: fout>>a; fout<<a; fout.close( ); Пример 1. Чтение из файла значения переменной. Будем читать из файла значение целочисленной переменной а; Для начала понадобится текстовый файл, содержащий значение переменной: • • Который мы сохраним в нашей рабочей папке Пример 1. Чтение из файла значения переменной. #include<iostream.h> #include <fstream.h> void main(void) { ifstream fout; cout<<"\nReading a value..."; fout.open(“Text.txt"); //чтения int a; fout>>a; fout.close(); cout<<"a="<<a; cin.get(); } // Заголовочный файл: функции ввода­вывода // Заголовочный файл: функции для работы с // файловыми потоками ввода и вывода // Главная функция //Начало тела главной функции //Объявляем переменную типа «поток входных // данных» //Выводим на экран текстовую строку //Открываем файл, в данном контексте для //Объявление целочисленной переменной //Читаем значение переменной из открытого // файла, сассоциированного на поток fout //Файл больше не нужен, закрываем его //Выводим значение а на экран, таким образом // смотрим, что же мы прочитали из файла //Ждем нажатия клавиши // Конец тела главной функции Пример 2. Запись значения переменной в файл. #include<iostream.h> #include <fstream.h> void main(void) { int a; cout<<"Input a: "; cin>>a; ofstream fout; fout.open("history.txt"); fout<<a; fout.close(); cin.get(); } // Заголовочный файл: функции ввода­вывода // Заголовочный файл: функции для работы с // файловыми потоками ввода и вывода // Главная функция //Начало тела главной функции // Целочисленная переменная а // Приглашение для ввода значения а // Читаем значение а // Объявление переменной типа «файловый //поток выходных данных» // Открываем файл для перезаписи // Записываем значение в файл // Файл больше не нужен, закрываем его // Ждем нажатия клавиши // Конец тела главной функции Пример 3. Обрабатываем ошибку, если файл не открылся. Borland C++ 5.0 Programmer's Guide #include <string.h> #include <stdio.h> #include <fcntl.h> #include <io.h> int main(void) { int handle; // «Номер» открытого файла, присваивается // операционной системой char msg[] = "Hello world"; // Текстовая строка if ((handle = open("TEST.txt", O_CREAT | O_TEXT)) == ­1) // Попытка открыть файл { // Если попытка не удалась perror("Error:"); // Выводим сообщение об ошибке return 1; // Завершаем выполнение главной функции, с // возвращением значения 1 } // Если попытка открытия файла удалась write(handle, msg, strlen(msg)); // Записываем в файл handle строку msg длинной // strlen(msg) байтов close(handle); // Закрываем файл return 0; // Завершаем главную функцию, с возвращением // значения 0 } Пример 4. Еще один способ чтения значения переменной из файла #include <stdio.h> FILE *fopen(const char *filename, const char *mode); Строка filename – имя файла, с которым хотим установить ассоциацию. Строка mode может принимать одно из следующих значений: Значение Описание r Открытие файла только для чтения. w Создание файла для записи. Если файл с таким именем уже существует, он будет перезаписан. a Открытие файла для дозаписи в конец файла. Если файл не существует, он будет создан. r+ Открытие существующего файла для модификации (чтения или записи). w+ Создание нового файла для модификации (чтения или записи). Если файл не существует, он будет создан. a+ Открытие файла для дозаписи в конец файла. Если файл не существует, он будет создан. Пример 4. Еще один способ чтения значения переменной из файла Некоторые удобные функции для работы с информацией в файлах: fputc(fgetc(in), out); ­ «кладет» в файл out то, что «взял» из файла in fgetc(in); ­ «берет» данные из файла in fprintf(out, “Hello world!!!\n"); ­ запись в файл out текстовой строки “Hello world!!!\n" fprintf(out, “a=%d\n“, a); ­ запись в файл out значения переменной а Пример 4. Еще один способ чтения значения переменной из файла /* Программа делает резервную копию AUTOEXEC.BAT */ #include <stdio.h> int main(void) { FILE *in, *out; // Объявляем две файловые переменные if ((in = fopen("\\AUTOEXEC.BAT", "rt")) //Пытаемся открыть входной файл (жирным) == NULL) //Если попытка оказалась неудачной { fprintf(stderr, "Cannot open input file.\n"); //Выводим сообщение об ошибке return 1; //Завершаем выполнение главной функции, //возвращая значение 1 } if ((out = fopen("\\AUTOEXEC.BAK", "wt")) // Пытаемся открыть выходной файл == NULL) // Если файл не открылся { fprintf(stderr, "Cannot open output file.\n"); // выводим сообщение об ошибке return 1; // Завершаем выполнение главной функции, // возвращая значение 1 } while (!feof(in)) // Пока не конец входного файла (!feof(in)) fputc(fgetc(in), out); // читаем данные из входного файла и пишем в // выходной fclose(in); // Закрываем входной файл fclose(out); // Закрываем выходной файл return 0; // Завершаем выполнение главной функции, // возвращая значение 0 } Borland C++ 5.0 Programmer's Guide Замечания • В именах файлов необходимо использовать знак двойного слэша (“c:\\WorkA\\Text.txt”). • Аналогично можно читать из файла значения нескольких переменных. В файле они должны быть разделены пробелами или записаны с новой строки. • Можно читать из файла или записывать в файл значения переменных всех типов. • Строки (как и любые значения) читаются «до первого пробела». Пример 5. Читаем и записываем несколько значений переменных #include<iostream.h> // Заголовочный файл: функции ввода­вывода #include <fstream.h> // Заголовочный файл: функции для работы с // файловыми потоками ввода и вывода void main(void) // Главная функция {int n1, n2; // Две целочисленные переменные ofstream fout; // Выходной файл (поток) cout<<"\nHistory export..."; // Вывод на экран текстовой строки fout.open("history.txt",ios::app); // Открываем файл для дозаписи fout<<“n1=“<<n1<<“ n2=“<<n2<<“ n1+n2=“<<n1+n2; // Записываем значения ||переменных n1 и n2 fout.close(); // Закрываем выходной файл cout<<"History written successful!\n"; // Надпись на экран «История записана успешно» ifstream finput; cout<<"\Reading values..."; finput.open("history1.txt"); finput>>n1>>n2; finput.close(); cout<<“n1=“<<n1<<“ n2=“<<n2; } // Входной файл (поток) // Вывод текстовой строки // Открываем файл для чнения // Читаем значения переменных // Закрываем файл // Выводим значения переменных на экран Пример 3. Чтение значений элементов массива #include<iostream.h> вывода #include <fstream.h> работы с void main(void) {int n1, a[4]; ifstream finput; cout<<"\Reading values..."; finput.open("history1.txt"); for(i=0;i<4;i++) {finput>>a[i];} finput.close(); for(i=0;i<4;i++) {cout<<“a[“<<i<<“]=“<<a[i];} } // Заголовочный файл: функции ввода­ // Заголовочный файл: функции для // файловыми потоками ввода и вывода // Главная функция // Целочисленная переменная i, массив // a, состоящий из четырех элементов // Входной файл (поток) // Вывод текстовой строки // Открываем файл для чтения // Читаем значения переменных // Закрываем файл // Выводим значения переменных на // экран Задания для самостоятельной работы: • • • • • • * Вывести в текстовый файл свое имя и возраст. * Прочитать из текстового файла значения двух целочисленных переменных, вывести на экран значение их суммы и произведения. * Прочитать из текстового файла значения двух целочисленных переменных, вывести в другой текстовый файл значение их суммы и произведения. * Прочитать из текстового файла значения элементов целочисленного массива (состоящего из 10 элементов) и записать из в другой текстовый файл. Вспомним сказку о репке. В текстовом файле находятся действительные значения силы, с которой может тянуть каждый из участников (Дедка, Бабка, Внучка, Жучка, Кошка и Мышка). Сохранить значения в массиве из 6 действительных элементов. С клавиатуры вводится действительное число – сила, с которой надо тянуть, чтобы вытянуть репку. Определить, сможет ли компания вытянуть репку, если сложит свои усилия. Найти произведение элементов 10­элементного массива из действительных чисел. Значения элементов прочитать из внешнего текстового файла. Результат сохранить в другой текстовый файл и показать на экране. * Сделать задания со всеми вариантами работы с файлами.