247.40K
Category: programmingprogramming

lec11

1.

Файлы С++

2.

Файлы
Различают два вида файлов: текстовые и бинарные.
Текстовый файл – компьютерный файл, содержащий текстовые данные,
как правило, организованные в виде строк.
Бинарный файл – файлы, в которых информация хранится в двоичном
виде, то есть во внутренней форме представления.
В С++ операции с файлами можно осуществлять в двух режимах:
форматированном (используя указатели) и потоковом.

3.

Открытие файла
FILE * fopen( const char * fname, const char * modeopen);
Если файл был успешно открыт, функция возвращает указатель на объект
файла. В противном случае, возвращается нулевой указатель NULL.

4.

Открытие двоичного файла
Для того, чтобы открыть двоичный файл, символ b должен быть включен
в режим доступа. Этот дополнительный символ b может быть добавлен в
конец строки, что даёт следующие режимы доступа к бинарным файлам:
rb, wb, ab, r+b, w+b, a+b или может быть вставлен между буквой и знаком +,
в случае со смешанными режимами: rb+, wb+, ab+
Для смешанных режимов, когда разрешены операции чтения и записи (или
добавления), следует обнулить данные функцией fflush или изменить
позицию внутреннего указателя (fseek fsetpos, rewind) после операции
чтения, за которой следует операция записи и, наоборот, после операции
записи, за которой следует операция чтения.

5.

Закрытие файла
int fclose(FILE * filestream);
Если файл успешно закрыт, возвращается нулевое значение.
В случае ошибки, возвращается EOF.

6.

Закрытие файла
int fclose(FILE * filestream);
Если файл успешно закрыт, возвращается нулевое значение.
В случае ошибки, возвращается EOF.

7.

Чтение и запись данных
Выбор способа чтения или записи данных зависит от того, какой должна быть
структура файла.
Если файл форматированный, то есть, является текстовым и состоит из
лексем, разделённых стандартными разделителями (пробел, табуляция,
перевод строки), обмен данными с ним можно выполнять методами:
• fscanf - для чтения
• fprintf - для записи
Первым параметром этих функций указывается файловая переменная, в
остальном работа совпадает со стандартными scanf и printf.

8.

Чтение и запись данных
Если имеется текстовый файл, состоящий из неструктурированных строк
(абзацев) текста, разделённых символами перевода строки, то при работе с
такими данными могут потребоваться следующие функции:
• fgetc и fputc - для посимвольного чтения и посимвольной записи данных;
• fgets и fputs - для чтения и записи строк с указанным максимальным
размером.
Как и в случае с функциями для чтения форматированных данных, у всех этих
методов имеются аналоги для работы со стандартным вводом/выводом.

9.

Чтение и запись данных
Если заранее неизвестное количество значений считываемых из файла
необходимо осуществлять проверку достигнут ли конец файла . Это позволяет
сделать стандартная функция feof (вернёт не 0, если прочитано всё) и
оператор цикла while.
Например:
while (!feof(f))
{
fscanf (f,"%f",&a);
//обработка числа a
}

10.

Пример

11.

Пример
#include <stdio.h>
fscanf(f, "%d", &k);
int main()
{
int i, j, n, m, l, k;
int **b, **c, **a, s;
FILE *f;
f = fopen("D:\\abc.txt", "r");
b = new int *[k];
for (i = 0; i < k; i++)
b[i] = new int[n];
for (i = 0; i < n; i++)
for (j = 0; j < k; j++)
fscanf(f, "%d", &b[i][j]);
fscanf(f, "%d%d", &m, &n);
fclose(f);
a = new int *[n];
for (i = 0; i < n; i++)
a[i] = new int[m];
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
fscanf(f, "%d", &a[i][j]);

12.

Пример
for (i = 0; i < m; i++)
{
for (j = 0; j < k; j++)
fprintf(f, "%d\t", c[i][j]);
fprintf(f, "\n");
}
fclose(f);
f = fopen("D:\\rez.txt", "w");
c = new int *[k];
for (i = 0; i < k; i++)
c[i] = new int[m];
for (i = 0; i < n; i++)
delete []a[i];
delete []a;
for (i = 0; i < m; i++)
for (j = 0; j < k; j++)
{
s = 0;
for (l = 0; l < n; l++)
s += a[i][l] * b[l][j];
c[i][j] = s;
}
for (i = 0; i < k; i++)
delete []b[i];
delete []b;
for (i = 0; i < k; i++)
delete []c[i];
delete []c;
fprintf(f, "%d\t%d\n", m, k);
return 0;
}

13.

Пример

14.

Проверка открытия файла
f = fopen("file name", "mode");
if (f != NULL)
{
// работа с данными из файла
}
else
{
// Обработка ситуации "Не удалось открыть файл"
}

15.

Чтение и запись данных
Основной способ работы с бинарными файлами – чтение и запись наборов
байт указанного размера. Основные функции для чтения и записи бинарных
данных – fread и fwrite соответственно. В базовой реализации они имеют по 4
параметра:
• void *buffer - нетипизированный указатель на место хранения данных;
• size_t (unsigned) size - размер элемента данных в байтах.
• size_t count - максимальное количество элементов, которые требуется
прочитать (записать);
• FILE *stream - указатель на структуру FILE.

16.

Пример
#include <stdio.h>
int main()
{
FILE *f = fopen ("D:\\data.dat","wb");
if (f != NULL)
{
const int n = 10;
int a[n];
for (int i = 0; i < n; i++)
a[i] = i + 1;
for (int i = 0; i < n; i++)
fwrite(&a[i], sizeof(int) , 1, f);
fclose(f);
}
else
puts ("Не удалось открыть файл");
return 0;
}
fwrite(a, sizeof(int), n, f);

17.

Пример
#include <stdio.h>
int main()
{
FILE *f = fopen ("D:\\data.dat","rb");
if (f != NULL)
{
const int n = 10;
int a[n];
for (int i = 0; i < n; i++)
fread(&a[i], sizeof(int) , 1, f);
fclose(f);
for (int i = 0; i < n; i++)
printf("%d\t", a[i]);
}
else
puts ("Не удалось открыть файл");
return 0;
}

18.

Чтение и запись данных
Для файлов, открытых в режиме "r+b", разрешены и чтение, и запись
(произвольный доступ). Поэтому при работе с такими файлами нужны
функции позиционирования файлового указателя:
• функции fgetpos и ftell позволяют выполнить чтение текущей позиции
указателя в файле;
• функции fseek и fsetpos позволяют осуществить переход к нужной позиции в
файле.

19.

Чтение и запись данных
fseek(f, 0, SEEK_END); //Встали на 0 байт от конца файла
int pos;
pos = ftell(f); //Получили текущую позицию в файле
if (pos < 0)
puts ("\nОшибка");
else if (!pos)
puts ("\nФайл пуст");
else
printf ("\nВ файле %ld байт", pos);

20.

Потоковый режим работы с файлами
#include <fstream.h>
Для работы с файлами имеется три потока:
• ifstream – для чтения данных из файла,
• ofstream – для записи в файл,
• fstream – для работы как в режиме чтения, так и записи.

21.

Чтение данных
Для записи данных в файл необходимо:
1. Описать файловый поток ofstream:
ofstream fname;
2. Открыть файл с помощью метода open.
3. Записать информацию в файл с помощью операции помещения в поток <<.
4. Закрыть файл методом close.

22.

Запись данных
Для записи данных в файл необходимо:
1. Описать файловый поток ifstream:
ifstream fname;
2. Открыть файл с помощью метода open.
3. Записать информацию в файл с помощью операции извлечения из потока
>>. При чтении каждой порции данных необходимо проверять, что чтение
данных возможно.
4. Закрыть файл методом close.

23.

Открытие файла
Открывается файл следующим образом:
fname.open("file", mode);
Здесь fname – имя файлового потока;
file – полное имя файла;
mode – режим работы с открытым файлом.

24.

Открытие файла
После удачного открытия файла в fname будет храниться true, в
противном случае – false.
После открытия файла для записи в него можно писать точно также как и на
консоль, только вместо стандартного потока вывода cout необходимо
указывать имя файлового потока:
fname << a;
Чтение данных из файла осуществляется также как и с консоли, только вместо
потока ввода cin используют файловый поток:
fname >> a;
Для проверки достигнут ли конец файла, случит метод fname.eof().

25.

Пример
if (fo)
{
for (i = 1; i <= n; i++)
{
cout << "ФИО: ";
getline(cin, temp);
fo << temp << '\t';
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
cout << "город: ";
getline(cin, temp);
fo << temp << '\t';
using namespace std;
int main()
{
SetConsoleOutputCP(1251);
SetConsoleCP(1251);
int i, n;
ofstream fo;
string temp;
cout << "телефон: ";
getline(cin, temp);
fo << temp;
if (i != n)
fo << endl;
}
fo.close();
cout << "n=";
cin >> n;
cin.ignore();
fo.open("D:\\abc.txt");
}
else
cout << "Ошибка при открытии файла";
return 0;
}

26.

Пример

27.

Пример
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
using namespace std;
struct men
{
string name;
string city;
long long int phone;
};
int main()
{
SetConsoleOutputCP(1251);
SetConsoleCP(1251);
int i, n, prev, next;
ifstream fi;
string temp;
men a;
fi.open("D:\\abc.txt");
if (fi)
{
cout << "В Витебске проживают: " << endl;
while (!fi.eof())
{
getline(fi, temp);
prev = 0;
next = temp.find('\t', prev + 1);
a.name = temp.substr(prev, next);
prev = next + 1;
next = temp.find('\t', prev);
a.city = temp.substr(prev, next - prev);
a.phone = stoi(temp.substr(next + 1, temp.length() - next));
if (a.city == "Витебск")
cout << a.name << '\t' << a.phone << endl;
i++;
}
fi.close();
}
else
cout << "Файл не найден" << endl;
return 0;
}

28.

Пример
English     Русский Rules