Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лаба 8 / Лабораторная_работа_№8_Токарев_0421

.docx
Скачиваний:
0
Добавлен:
26.06.2025
Размер:
179.14 Кб
Скачать

МИНОБРНАУКИ РОССИИ

Санкт-Петербургский государственный

электротехнический университет

«ЛЭТИ» им. В.И. Ульянова (Ленина)

Кафедра Электротехнологической и преобразовательной техники

отчет

по лабораторной работе № 8

по дисциплине «Информационные технологии»

Тема: Форматное преобразование данных

Студент гр. 0421

Токарев А.А.

Преподаватель

Чмиленко Ф.В.

Санкт-Петербург

2021

Цель работы: Освоение техники работы с файлами данных помощью библиотеки языка С.

Задания:

  1. Форматированное сохранение массива сложной структуры в текстовый файл

  2. Чтение массива сложной структуры из текстового файла

  3. Определение размера файла

  4. Запись в файл в двоичном формате

  5. Чтение из файла двоичного формата

  6. Чтение элемента массива из произвольного места файла двоичного формата

  7. Запись элемента массива в произвольное место файла двоичного формата

Дополнительные задания:

  1. Ввод/вывод из фала с помощью потокового вывода языка С++

Ход работы:

Задание 1.

Создадим программу, в которой реализуем открытие текстового файла с помощью open и сохранит в него заранее созданный и инициализированный массив структур:

#include <stdio.h>

#include <iostream>

using namespace std;

struct A {

short a;

double b;

char c[20];

float d;

short e;

};

int main()

{

system("chcp 1251");

system("cls");

FILE* inp; //указатель на файл

A data[] =

{

{20, -2.44, "Язык С++", 13.33, 12},

{-1, 44.21, "Язык FORTRAN", -0.33, 3},

{0, 12.33, "Язык Pascal", 1.23, 14},

{40, -66.12, "Язык Python", 2.11, 11},

{28, 28.28, "Язык С", 11.22, -5},

{44, 55.55, "Язык C#", 25.22, 54},

{-4, 41.44, "Язык Ruby", 243.22, 777},

{2, 2.22, "Язык Java", 77.77, 0},

{55, 51.15, "Язык JavaScript", 15.15, 99},

{99, 54.54, "Язык PHP", 51.55, 28}

};

inp = fopen("C:\\Users\\Admin\\Desktop\\data.txt", "w"); //открываем файл для записи

for (int i = 0; i < 10; i++)

{

fprintf(inp, "%d %f %s %f %d\n", data[i].a, data[i].b, data[i].c, data[i].d, data[i].e); //запись в файл

}

fclose(inp); //закрываем файл

return 0;

}

Рисунок 1 – Содержание файла data.txt

Доработаем программу так, чтобы имя файла можно было задавать с клавиатуры:

#include <stdio.h>

#include <iostream>

using namespace std;

struct A {

short a;

double b;

char c[20];

float d;

short e;

};

int main()

{

system("chcp 1251");

system("cls");

FILE* inp; //указатель на файл

char str[80];

A data[] =

{

{20, -2.44, "Язык С++", 13.33, 12},

{-1, 44.21, "Язык FORTRAN", -0.33, 3},

{0, 12.33, "Язык Pascal", 1.23, 14},

{40, -66.12, "Язык Python", 2.11, 11},

{28, 28.28, "Язык С", 11.22, -5},

{44, 55.55, "Язык C#", 25.22, 54},

{-4, 41.44, "Язык Ruby", 243.22, 777},

{2, 2.22, "Язык Java", 77.77, 0},

{55, 51.15, "Язык JavaScript", 15.15, 99},

{99, 54.54, "Язык PHP", 51.55, 28}

};

cout << "Введите имя файла:" << endl;

gets(str);

inp = fopen(str, "w"); //открываем файл для записи

for (int i = 0; i < 10; i++)

{

fprintf(inp, "%d %f %s %f %d\n", data[i].a, data[i].b, data[i].c, data[i].d, data[i].e); //запись в файл

}

fclose(inp); //закрываем файл

system("pause");

return 0;

}

Рисунок 2 – Результат работы доработанной программы

Рисунок 3 – Содержпние файла file1.txt

Задание 2.

Отредактируем созданный в задании 1 файл data.txt, удалив из него последние две строчки. Разработаем программу для чтения отредактированного файла в массив структур с помощью функции fscanf. Имя файла будем задавать с консоли, предусмотрев ситуацию, когда запрашиваемого файла не окажется на диске. Для вывода на консоль прочитанного из файла, добавим функцию void View(*char, int):

#include <stdio.h>

#include <iostream>

#include <string.h>

using namespace std;

struct A {

short a;

double b;

char c[20];

float d;

short e;

};

void View(struct A data[], int i)

{

for (int j = 0; j < i; j++)

{

printf("%hd %.2lf %s %.2f %hd\n", data[j].a, data[j].b, data[j].c , data[j].d, data[j].e);

}

}

int main()

{

system("chcp 1251");

system("cls");

int i = 0;

FILE* inp; //указатель на файл

char str[80], tmp1[15][15], tmp2[15][15];

A data[15];

M1:cout << "Введите имя файла:" << endl;

gets(str);

inp = fopen(str, "r+"); //открываем файл для записи

if(fopen(str, "r+") == NULL)

{

cout << "Ошибка!Данного файла нет на диске!Введите имя файла:" << endl;

fflush(stdin);

goto M1;

}

while(!feof(inp))

{

fscanf(inp, "%hd %lf %s %s %f %hd\n", &data[i].a, &data[i].b, tmp1[i], tmp2[i], &data[i].d, &data[i].e); //чтение из файла

snprintf(data[i].c, sizeof(data[i].c), "%s %s", tmp1[i], tmp2[i]);

i++;

}

View(data, i);

fclose(inp); //закрываем файл

system("pause");

return 0;

}

Рисунок 4 – Результат работы программы по чтению данных из файла

Задание 3.

Доработаем предыдущее задание. Определим размер выбранного для чтения файла с помощью функций fseek и ftell:

#include <stdio.h>

#include <iostream>

#include <string.h>

using namespace std;

struct A {

short a;

double b;

char c[20];

float d;

short e;

};

void View(struct A data[], int i)

{

for (int j = 0; j < i; j++)

{

printf("%hd %.2lf %s %.2f %hd\n", data[j].a, data[j].b, data[j].c , data[j].d, data[j].e);

}

}

int main()

{

system("chcp 1251");

system("cls");

int i = 0;

int sz;

FILE* inp; //указатель на файл

char str[80], tmp1[15][15], tmp2[15][15];

A data[15];

M1:cout << "Введите имя файла:" << endl;

gets(str);

inp = fopen(str, "r+"); //открываем файл для записи

if(fopen(str, "r+") == NULL)

{

cout << "Ошибка!Данного файла нет на диске!Введите имя файла:" << endl;

fflush(stdin);

goto M1;

}

fseek(inp, 0, SEEK_END);

sz = ftell(inp);

fseek(inp, 0, SEEK_SET);

while(!feof(inp))

{

fscanf(inp, "%hd %lf %s %s %f %hd\n", &data[i].a, &data[i].b, tmp1[i], tmp2[i], &data[i].d, &data[i].e); //чтение из файла

snprintf(data[i].c, sizeof(data[i].c), "%s %s", tmp1[i], tmp2[i]);

i++;

}

View(data, i);

cout << "Размер файла равен " << sz << " байт(ов)" << endl;

fclose(inp); //закрываем файл

system("pause");

return 0;

}

Рисунок 5 – Результат работы программы по определению размера файла

Задание 4.

Разработаем программу, которая сохраняет массив структур в бинарном файле с помощью функции fwrite. Сравним размер полученного файла с размером файла текстового формата:

#include <stdio.h>

#include <iostream>

using namespace std;

struct A {

short a;

double b;

char c[20];

float d;

short e;

};

int main()

{

system("chcp 1251");

system("cls");

FILE* inp; //указатель на файл

char str[80];

int sz;

A data[] =

{

{20, -2.44, "Язык С++", 13.33, 12},

{-1, 44.21, "Язык FORTRAN", -0.33, 3},

{0, 12.33, "Язык Pascal", 1.23, 14},

{40, -66.12, "Язык Python", 2.11, 11},

{28, 28.28, "Язык С", 11.22, -5},

{44, 55.55, "Язык C#", 25.22, 54},

{-4, 41.44, "Язык Ruby", 243.22, 777},

{2, 2.22, "Язык Java", 77.77, 0}

};

cout << "Введите имя файла:" << endl;

gets(str);

inp = fopen(str, "wb+"); //открываем файл для записи

for (int i = 0; i < 8; i++)

{

fwrite(&data[i], sizeof(struct A),1,inp);

}

fseek(inp, 0, SEEK_END);

sz = ftell(inp);

fclose(inp); //закрываем файл

cout << "размер файла равен " << sz << "байт(ов)" << endl;

system("pause");

return 0;

}

Рисунок 6 – Результат работы программы по сохранению структуры в файл в двоичном формате

Задание 5.

Разработаем программу, которая читает данные в массив из файла двоичного формата с помощью функции fread. Так как количество информации, содержащееся в файле, нам неизвестно по условию, будем использовать динамическую память:

#include <stdio.h>

#include <iostream>

using namespace std;

struct A {

short a;

double b;

char c[20];

float d;

short e;

};

void View(struct A data[], int i)

{

for (int j = 0; j < i; j++)

{

cout << data[j].a << " " << data[j].b << " " << data[j].c << " " << data[j].d << " " << data[j].e << endl;

}

}

int main()

{

system("chcp 1251");

system("cls");

FILE* inp; //указатель на файл

char str[80];

int sz, sz_mas;

cout << "Введите имя файла:" << endl;

gets(str);

inp = fopen(str, "r+b"); //открываем файл для чтения

fseek(inp, 0, SEEK_END);

sz = ftell(inp);

rewind(inp);

sz_mas = sz/(sizeof(short)+sizeof(double)+sizeof(char [20]) + sizeof(float) + sizeof(short));

A *data = new A [sz_mas];

for (int i = 0; i < sz_mas; i++)

{

fread(&data[i].a, sizeof(data[i].a) ,1,inp);

fread(&data[i].b, sizeof(data[i].b) ,1,inp);

fread(&data[i].c, sizeof(data[i].c) ,1,inp);

fread(&data[i].d, sizeof(data[i].d) ,1,inp);

fread(&data[i].e, sizeof(data[i].e) ,1,inp);

}

fclose(inp); //закрываем файл

View(data, sz_mas);

cout << sizeof (struct A);

system("pause");

return 0;

}

Рисунок 7 – Результат работы программы по чтению из файла двоичного формата

Задание 6.

Разработаем программу, которая читает один заданный элемент массива из файла. Номер элемента зададим с консоли:

#include <stdio.h>

#include <iostream>

using namespace std;

struct A {

short a;

double b;

char c[20];

float d;

short e;

};

int main()

{

system("chcp 1251");

system("cls");

FILE* inp; //указатель на файл

char str[80];

int sz, n;

cout << "Введите имя файла:" << endl;

gets(str);

cout << "Введите номер строки: " << endl;

cin >> n;

inp = fopen(str, "r+b"); //открываем файл для чтения

sz = (sizeof(short)+sizeof(double)+sizeof(char [20]) + sizeof(float) + sizeof(short)) * (n - 1);

fseek(inp, sz, SEEK_SET);

A data;

fread(&data.a, sizeof(data.a) ,1,inp);

fread(&data.b, sizeof(data.b) ,1,inp);

fread(&data.c, sizeof(data.c) ,1,inp);

fread(&data.d, sizeof(data.d) ,1,inp);

fread(&data.e, sizeof(data.e) ,1,inp);

fclose(inp); //закрываем файл

cout << data.a << " " << data.b << " " << data.c << " " << data.d << " " << data.e << endl;

system("pause");

return 0;

}

Рисунок 8 – Результат работы программы по чтению одного заданного элемента массива из двоичного файла

Задание 7.

Разработаем программу, которая записывает одну строку массива в заданное место файла. Элементы структуры и номер строки будем задавать с консоли:

#include <stdio.h>

#include <iostream>

#include <string>

using namespace std;

struct A {

short a;

double b;

char c[20];

float d;

short e;

};

void View(struct A data[], int i)

{

cout <<"Новый массив данных:" << endl;

for (int j = 0; j < i; j++)

{

cout << data[j].a << " " << data[j].b << " " << data[j].c << " " << data[j].d << " " << data[j].e << endl;

}

}

int main()

{

system("chcp 1251");

system("cls");

FILE* inp; //указатель на файл

char str[80];

int sz1, n, sz_mas, sz;

A temp;

char tmp1[20];

char tmp2[20];

cout << "Введите имя файла:" << endl;

gets(str);

cout << "Введите номер строки: " << endl;

cin >> n;

cout << "Введите новую запись:" << endl;

scanf("%hd %lf %s %s %f %hd", &temp.a, &temp.b, tmp1, tmp2, &temp.d, &temp.e);

snprintf(temp.c, 20, "%s %s", tmp1, tmp2);

inp = fopen(str, "r+b"); //открываем файл для чтения

fseek(inp, 0, SEEK_END);

sz = ftell(inp);

rewind(inp);

sz1 = (sizeof(short)+sizeof(double)+sizeof(char [20]) + sizeof(float) + sizeof(short)) * (n - 1);

fseek(inp, sz1, SEEK_SET);

fwrite(&temp.a, sizeof(temp.a) ,1,inp);

fwrite(&temp.b, sizeof(temp.b) ,1,inp);

fwrite(&temp.c, sizeof(temp.c) ,1,inp);

fwrite(&temp.d, sizeof(temp.d) ,1,inp);

fwrite(&temp.e, sizeof(temp.e) ,1,inp);

rewind(inp);

sz_mas = sz/(sizeof(short)+sizeof(double)+sizeof(char [20]) + sizeof(float) + sizeof(short));

A *data = new A [sz_mas];

for (int i = 0; i < sz_mas; i++)

{

fread(&data[i].a, sizeof(data[i].a) ,1,inp);

fread(&data[i].b, sizeof(data[i].b) ,1,inp);

fread(&data[i].c, sizeof(data[i].c) ,1,inp);

fread(&data[i].d, sizeof(data[i].d) ,1,inp);

fread(&data[i].e, sizeof(data[i].e) ,1,inp);

}

fclose(inp); //закрываем файл

View(data, sz_mas);

system("pause");

return 0;

}

Рисунок 9 – Результат работы программы по записи строки массива в заданное место файла

Дополнительное задание.

Разработаем программу, в которой реализуем задания 1 и 2 с помощью потоковой библиотеки работы с файлами С++:

#include <stdio.h>

#include <iostream>

#include <string>

#include <fstream>

using namespace std;

struct A {

short a;

double b;

string c;

float d;

short e;

};

int main()

{

system("chcp 1251");

system("cls");

char str[80];

int i = 0;

string s;

A data[] =

{

{20, -2.44, "Язык С++", 13.33, 12},

{-1, 44.21, "Язык FORTRAN", -0.33, 3},

{0, 12.33, "Язык Pascal", 1.23, 14},

{40, -66.12, "Язык Python", 2.11, 11},

{28, 28.28, "Язык С", 11.22, -5},

{44, 55.55, "Язык C#", 25.22, 54},

{-4, 41.44, "Язык Ruby", 243.22, 777},

{2, 2.22, "Язык Java", 77.77, 0},

{55, 51.15, "Язык JavaScript", 15.15, 99},

{99, 54.54, "Язык PHP", 51.55, 28}

};

A data1[80];

cout << "Введите имя файла:" << endl;

gets(str);

fstream inp;

inp.open(str);

for(int i = 0; i < 10; i++)

{

inp << data[i].a << " " << data[i].b << " " << data[i].c << " " << data[i].d << " " << data[i].e << endl;

}

inp.close(); //закрываем файл

inp.open(str);

while (!inp.eof())

{

getline(inp, s);

cout << s << "\n";

}

inp.close();

system("pause");

return 0;

}

Рисунок 10 – Результат работы программы по потоковому вводу/выводу из файла

Выводы:

В данной лабораторной работе были изучены основные функции для работы с файлами языка си. Были разработаны программы, выполняющие форматированный ввод массива структур в текстовый файл и форматированный вывод массива структур из текстового файла. Также был определен размер получившегося текстового файла.

Кроме того, были разработаны программы, выполняющие форматированный ввод массива структур в двоичный файл и форматированный вывод массива структур из двоичного файла. Также был определен размер получившегося двоичного файла и проведено сравнение размера двоичного файла и текстового. Двоичный файл занимает меньше места на диске.

С помощью функции fseek были разработаны программы по чтению и записи элемента массива в бинарный файл.

Кроме того, был выполнен форматированный ввод и вывод массива структур в файл был с помощью инструментов потокового ввода/вывода языка С++.