C++ При завершении программы с использованием ifstring.read при считывании данных с файла выдаёт ошибку
Вызвано необработанное исключение: нарушение доступа для чтения. _Val было 0x218C0D5E4F8.
Сам файл спокойно считывается и записывается в массивы, но программа не может просто закрыться. Для интереса решил этот блок кода запихнуть отдельно в условие и именно когда компилятор выходит из него, выдаёт эту ошибку. Если файл был пустой, то всё нормально.
Проблема с этим блоком :
ifstream fSPISOKin;
fSPISOKin.open("fSPISOK.txt");
PROGRAMMER temp;
while (fSPISOKin.read((char*)&temp, sizeof(PROGRAMMER))) {
ReSize(SPISOK, Null_I, size_programmer, 1); //функция для увеличения размера динамического массива
SPISOK[size_programmer-1] = temp;
}
Сам код:
/*
Необходимо описать структуру с именем PROGRSPISOKMMER, содержащую следующие поля:
- NAME - фамилия, имя;
- DAY - день рождения (массив из трех чисел);
- LANGUAGE – язык программирования;
- TelNumber ¬¬– Телефонный номер;
- Adress – Адрес;
- Email –Электронная почта;
- dolzhnost – Должность;
- status – Статус;
- Project – Проект;
- Group – Группа;
Разработать приложение, выполняющее следующие действия:
- ввод с клавиатуры данных в массив SPISOK, состоящий из восьми элементов типа PROGRAMMER; записи должны быть отсортированы по фамилии в алфавитном порядке;
- фильтрация массива данных по различным критериям любого вида в любом количестве, критерии фильтрации не должны повторяться;
- если таких программистов нет, выводить соответствующее сообщение на экран;
- добавление в базу данных новых сотрудников;
- удаление сотрудников из базы данных.
- изменение параметров;
- вывод сотрудников отсортированным пофамильно в алфавитном порядке;
- запись данных в файл с последующим считыванием.
*/
#define SIZE_PARAMETRS 10
#include <iostream>
#include <string>
#include <Windows.h>
#include <algorithm>
#include <iomanip>
#include <fstream>
using namespace std;
//Создание структуры параметров фильтрации
struct parametrs_ST {
int num{0};
string name;
bool active = true;
};
parametrs_ST parametrs[SIZE_PARAMETRS];
// Создание структуры PROGRAMMER
class PROGRAMMER {
public:
string NAME;
int DAY[3];
string LANGUAGE;
string TelNumber;
string Adress;
string Email;
string dolzhnost;
string status;
string Project;
string Group;
};
//Инициализация пустых указателей
PROGRAMMER* Null_P = NULL;
int* Null_I = NULL;
//Процедура для ввода данных
PROGRAMMER Enter() {
PROGRAMMER temp;
std::cout << "Введите имя фамилию программиста" << ": ";
getline(cin, temp.NAME);
std::cout << "Введите день рождения программиста (DD MM YYYY): ";
cin >> temp.DAY[0] >> temp.DAY[1] >> temp.DAY[2];
cin.ignore();
std::cout << "Введите язык программиста : ";
getline(cin, temp.LANGUAGE);
std::cout << "Введите телефонный номер: ";
getline(cin, temp.TelNumber);
std::cout << "Введите Адрес: ";
getline(cin, temp.Adress);
std::cout << "Введите Электронную почту: ";
getline(cin, temp.Email);
std::cout << "Введите Должность: ";
getline(cin, temp.dolzhnost);
std::cout << "Введите Статус сотрудника: ";
getline(cin, temp.status);
std::cout << "Введите проект над которым работает сотрудник: ";
getline(cin, temp.Project);
std::cout << "Введите Группу сотрудника: ";
getline(cin, temp.Group);
std::cout << "\n";
return temp;
}
//Процедура для присвоению указателю новых значений
void Rewrite(PROGRAMMER*& Main_P,PROGRAMMER* temp,int*&Main_int,int *temp_int,int new_size){
if (Main_P != NULL) {
delete[]Main_P;
Main_P = new PROGRAMMER[new_size];
for (int i = 0; i < new_size; i++)
Main_P[i] = temp[i];
}
else {
delete[]Main_int;
Main_int = new int[new_size];
for (int i = 0; i < new_size; i++)
Main_int[i] = temp_int[i];
}
}
//Процедура на изменение размера массива
void ReSize(PROGRAMMER*& Prog,int *&into,int &size_num ,int num) {
size_num += num;
if (Prog == NULL) {
int* temp_I = new int[size_num];
if(num>0)
for (int i = 0; i < size_num - 1; i++)
temp_I[i] = into[i];
else
for (int i = 0; i <= size_num - 1; i++)
temp_I[i] = into[i];
Rewrite( Null_P, Null_P,into,temp_I, size_num);
}
else {
PROGRAMMER* temp = new PROGRAMMER[size_num];
if(num>0)
for (int i = 0; i < size_num - 1; i++)
temp[i] = Prog[i];
else
for (int i = 0; i <= size_num - 1; i++)
temp[i] = Prog[i];
Rewrite(Prog, temp, Null_I, Null_I, size_num);
}
}
//Процедура для добавления значений в массив
void ADD(PROGRAMMER*& arr,int &size_arr,int num) {
ReSize(arr,Null_I, size_arr, 1);
arr[size_arr - 1] = Enter();
}
//Процедура для вывода массива
int *Search(PROGRAMMER*& philtr, int& size, int philtr_num) {
int *find= new int[1];
int size_find = 1;
find[0] = 1;
switch (philtr_num) {
case 1: {
string searchName;
std::cout << "Введите Имя Фамилию: ";
getline(cin, searchName);
// Поиск и вывод по Имени Фамилии
for (int i = 0; i < size; i++)
if (searchName == philtr[i].NAME) {
ReSize(Null_P, find, size_find, 1);
find[size_find - 1] = i;
}
break; }
case 2: {
int searchDAY[3]{ 0,0,0 };
std::cout << "Введите дату рождения: ";
cin >> searchDAY[0] >> searchDAY[1] >> searchDAY[2];
cin.ignore();
// Поиск и вывод программистов с определённой датой рождения
for (int i = 0; i < size; i++)
if (searchDAY[0] == philtr[i].DAY[0] && searchDAY[1] == philtr[i].DAY[1] && searchDAY[2] == philtr[i].DAY[2]) {
ReSize(Null_P, find, size_find, 1);
find[size_find - 1] = i;
}
break; }
case 3: {
string searchLanguage;
std::cout << "Введите язык программирования: ";
getline(cin, searchLanguage);
// Поиск и вывод программистов пишущих на определенном языке
for (int i = 0; i < size; i++)
if (searchLanguage == philtr[i].LANGUAGE){
ReSize(Null_P, find, size_find, 1);
find[size_find - 1] = i; }
break; }
case 4: {
string SearchTelNumber;
std::cout << "Введите номер телефона: ";
getline(cin, SearchTelNumber);
// Поиск и вывод программистов с определённым номером телефона
for (int i = 0; i < size; i++)
if (SearchTelNumber == philtr[i].TelNumber) {
ReSize(Null_P, find, size_find, 1);
find[size_find - 1] = i; }
break; }
case 5: {
string searchAdress;
std::cout << "Введите адрес: ";
getline(cin, searchAdress);
// Поиск и вывод программистов живущих по определенному адресу
for (int i = 0; i < size; i++)
if (searchAdress == philtr[i].Adress) {
ReSize(Null_P, find, size_find, 1);
find[size_find - 1] = i;
}
break; }
case 6:
{
string searchEmail;
std::cout << "Введите электронную почту: ";
getline(cin, searchEmail);
// Поиск и вывод программистов живущих по определенному адресу
for (int i = 0; i < size; i++)
if (searchEmail == philtr[i].Email) {
ReSize(Null_P, find, size_find, 1);
find[size_find - 1] = i;
}
break; }
case 7: {
string searchDolzhnost;
std::cout << "Введите должность: ";
getline(cin, searchDolzhnost);
// Поиск и вывод программистов живущих по определенному адресу
for (int i = 0; i < size; i++)
if (searchDolzhnost == philtr[i].dolzhnost) {
ReSize(Null_P, find, size_find, 1);
find[size_find - 1] = i;
}
break; }
case 8: {
string searchStatus;
std::cout << "Введите статус: ";
getline(cin, searchStatus);
// Поиск и вывод программистов живущих по определенному адресу
for (int i = 0; i < size; i++)
if (searchStatus == philtr[i].status) {
ReSize(Null_P, find, size_find, 1);
find[size_find - 1] = i;
}
break; }
case 9: {
string searchProject;
std::cout << "Введите проект: ";
getline(cin, searchProject);
// Поиск и вывод программистов живущих по определенному адресу
for (int i = 0; i < size; i++)
if (searchProject == philtr[i].Project) {
ReSize(Null_P, find, size_find, 1);
find[size_find - 1] = i;
}
break; }
case 10: {
string searchGroup;
std::cout << "Введите группу: ";
getline(cin, searchGroup);
// Поиск и вывод программистов живущих по определенному адресу
for (int i = 0; i < size; i++)
if (searchGroup == philtr[i].Group) {
ReSize(Null_P, find, size_find, 1);
find[size_find - 1] = i;
}
break; }
}
find[0] = size_find;
return find;
}
void Vivod(PROGRAMMER *A,int point_start,int size) {
for(int i=point_start;i<size+point_start;i++)
std::cout << '\n' << A[i].NAME << "\n" << A[i].DAY[0] << " " << A[i].DAY[1] << " " << A[i].DAY[2] << "\n" << A[i].LANGUAGE << "\n" << A[i].TelNumber << "\n" << A[i].Adress << "\n" << A[i].Email << "\n" << A[i].dolzhnost << "\n" << A[i].status << "\n" << A[i].Project << "\n" << A[i].Group << "\n" << setfill('-') << setw(30) << "\n";
}
//Процедура фильтрации
void philtrf(PROGRAMMER *&philtr,int &size) {
PROGRAMMER *temp = new PROGRAMMER[size];
for (int i = 0; i < SIZE_PARAMETRS; i++) {
if(parametrs[i].active==true)
std::cout << parametrs[i].num << ") " << parametrs[i].name<<endl;
}
std::cout << "Введите номер интересующего параметра фильтрации: ";
int philtr_num;
cin >> philtr_num;
cin.ignore();
parametrs[philtr_num - 1].active = false;
int new_size = 0;
int* find=Null_I;
find = Search(philtr,size,philtr_num);
for(int i=1;i<find[0];i++) {
temp[new_size] = philtr[find[i]];
new_size++;
}
Rewrite(philtr, temp, Null_I, Null_I, new_size);
size = new_size;
}
// Функция которая сравнивает 2 программистов по их фамилии
bool compareProgrammers(PROGRAMMER a, PROGRAMMER b) {
// Разделение имени и фамилии
string aFirst, aLast, bFirst, bLast;
size_t spacePosA = a.NAME.find(' ');
aFirst = a.NAME.substr(0, spacePosA);
aLast = a.NAME.substr(spacePosA + 1);
size_t spacePosB = b.NAME.find(' ');
bFirst = b.NAME.substr(0, spacePosB);
bLast = b.NAME.substr(spacePosB + 1);
// Сравнение фамилий
return aLast < bLast;
}
int main() {
int size_programmer = 0;
PROGRAMMER* SPISOK = new PROGRAMMER[size_programmer];
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
ifstream fSPISOKin;
fSPISOKin.open("fSPISOK.txt");
PROGRAMMER temp;
while (fSPISOKin.read((char*)&temp, sizeof(PROGRAMMER))) {
ReSize(SPISOK, Null_I, size_programmer, 1);
SPISOK[size_programmer-1] = temp;
}
fSPISOKin.close();
ofstream fSPISOKout("fSPISOK.txt");
parametrs[0] = { 1, "Имя Фамилия" };
parametrs[1] = { 2, "День рождения" };
parametrs[2] = { 3, "Язык Программирования" };
parametrs[3] = { 4, "Номер телефона" };
parametrs[4] = { 5, "Адрес" };
parametrs[5] = { 6, "Электронная почта" };
parametrs[6] = { 7, "Должность" };
parametrs[7] = { 8, "Статус" };
parametrs[8] = { 9, "Проект" };
parametrs[9] = { 10, "Группа" };
int option=0;
while(option!=6) {
std::cout << "\n1)Фильтрация\n2)Добавление\n3)Удаление\n4)Вывод\n5)Редактирование(Coming Soon)\n6)Закрытие программы\nВыберите действие: ";
cin >> option;
cin.ignore();
switch (option) {
//Фильтрация
case 1: {
int size_philtr = size_programmer;
PROGRAMMER* philtr = new PROGRAMMER[size_philtr];
for (int i = 0; i < size_programmer; i++)
philtr[i] = { SPISOK[i] };
std::cout << "Введите количество параметров фильтрации: ";
int kolvo_pov;
cin >> kolvo_pov;
cin.ignore();
while (kolvo_pov > SIZE_PARAMETRS) {
std::cout << "\n\n ERROR:Недопустимое количество параметров \n\n";
cin >> kolvo_pov;
}
for (int i = 0; i < kolvo_pov; i++)
philtrf(philtr, size_philtr);
for (int i = 0; i < SIZE_PARAMETRS; i++)//возвращение параметров в активное состояние
parametrs[i].active = true;
std::cout << "Результат сортировки: \n";
Vivod(philtr, 0, size_philtr);
break;
}
//Добавление
case 2: {
int kolvo_vvod;
std::cout << "Введите количество сотрудников на добавление: ";
cin >> kolvo_vvod;
cin.ignore();
for (int i = 0; i < kolvo_vvod; i++)
ADD(SPISOK, size_programmer, i + 1);
break;
}
//Удаление
case 3: {
int kolvo_delete;
bool num_del = false;
while (!num_del) {
std::cout << "Введите количество сотрудников на удаление: ";
cin >> kolvo_delete;
cin.ignore();
if (kolvo_delete > size_programmer)
std::cout << "ERROR:Недопустимое количество\n";
else
num_del = true;
}
for (int i = 0; i < kolvo_delete; i++) {
int* MB_DEL = NULL;
MB_DEL = Search(SPISOK, size_programmer, 1);
for (int j = 1; j < MB_DEL[0]; j++) {
std::cout << j<<")\n";
Vivod(SPISOK, MB_DEL[j], 1);
}
bool B_del{ false };
while (!B_del) {
std::cout << "Какого из сотрудников удалить: ";
int num_del;
cin >> num_del;
if (!(num_del > MB_DEL[0]-1))
B_del = true;
else
std::cout << "ERROR:Выберите из предоставленных чисел\n";
}
cin.ignore();
//Смещение удаляемого сотрудника в конец массива
for (int i = MB_DEL[num_del]; i+1 < size_programmer; i++) {
PROGRAMMER temp = SPISOK[i];
SPISOK[i] = SPISOK[i + 1];
SPISOK[i + 1] = temp;
}
//Удаление сотрудника
ReSize(SPISOK, Null_I, size_programmer, -1);
std::cout << "Удаление произошло успешно\n";
}
break;
}
//Вывод
case 4: {
sort(SPISOK, SPISOK + size_programmer, compareProgrammers);
Vivod(SPISOK, 0, size_programmer);
break;
}
//Изменение
case 5: {
int* MB_IZM = NULL;
MB_IZM = Search(SPISOK, size_programmer, 1);
for (int j = 1; j < MB_IZM[0]; j++) {
std::cout << j << ")\n";
Vivod(SPISOK, MB_IZM[j], 1);
}
bool B_del{ false };
while (!B_del) {
std::cout << "Какого из сотрудников редактировать: ";
int num_del;
cin >> num_del;
if (!(num_del > MB_IZM[0] - 1))
B_del = true;
else
std::cout << "ERROR:Выберите из предоставленных чисел\n";
}
cin.ignore();
for (int i = 0; i < SIZE_PARAMETRS; i++)
std::cout << parametrs[i].num << ") " << parametrs[i].name << endl;
int num_param;
std::cout << "Введите параметр для изменения: \n";
std::cin >> num_param;
cin.ignore();
cout << "Введите новое значение: ";
if (num_param == 2) {
cin >> SPISOK[MB_IZM[1]].DAY[0] >> SPISOK[MB_IZM[1]].DAY[1] >> SPISOK[MB_IZM[1]].DAY[2];
cin.ignore();
}
else{
string temp;
getline(cin, temp);
switch (num_param) {
case 1:
SPISOK[MB_IZM[1]].NAME = temp; break;
case 3:
SPISOK[MB_IZM[1]].LANGUAGE = temp; break;
case 4:
SPISOK[MB_IZM[1]].TelNumber = temp; break;
case 5:
SPISOK[MB_IZM[1]].Adress = temp; break;
case 6:
SPISOK[MB_IZM[1]].Email = temp; break;
case 7:
SPISOK[MB_IZM[1]].dolzhnost = temp; break;
case 8:
SPISOK[MB_IZM[1]].status = temp; break;
case 9:
SPISOK[MB_IZM[1]].Project = temp; break;
case 10:
SPISOK[MB_IZM[1]].Group = temp; break;
}
}
cout << "Изменения успешно сохранились.\n";
break;
}
//Выход из программы
case 6:
sort(SPISOK, SPISOK + size_programmer, compareProgrammers);
for (int i = 0; i < size_programmer; i++) {
fSPISOKout.write((char*)&SPISOK[i], sizeof(PROGRAMMER));
}
break;
//Значения вне диапазона действий
default:
std::cout << "ERROR:Недопустимое действие\n";
break;
}
}
fSPISOKout.close();
return 0;
}