Двоичные файлы — запись элементов структуры в двоичный файл и чтение их с использованием fstream с переполнением стека

Все еще новичок в мире C ++, и следующий вопрос из-за домашнего задания! Я не нашел много способов помочь в поиске по ранее отвеченным вопросам или Google, не означает, что я не пропустил это.

Цели домашнего задания:
1.) Взять введенную пользователем информацию и сохранить ее в двоичном файле.
2.) Читать эти данные позже.

У меня есть массив до 10 структур, структура принимает массив символов имени пользователя, массив символов номера телефона пользователя и плавающую зарплату. Когда я ввожу несколько тестовых случаев, файл пишет, я предполагаю, правильно. Когда я иду, чтобы прочитать значения, первое имя хорошо распечатывается, как и первый номер телефона. Число с плавающей точкой дает мне значение -4013602080 независимо от того, какое значение я ввел в тестовом примере. Оттуда он идет вниз по склону. Я пытаюсь это с помощью. Мой вопрос сводится к двум частям: правильно ли я записываю элементы структуры в файл, и как мне читать с плавающей запятой из двоичного файла? (или было бы выгодно использовать fopen и fclose?) Подсказки или ссылки были бы замечательными.

заголовок

//my header
#ifndef USERS_H
#define USERS_H#include <iostream>
#include <cstring>
#include <cstdlib>
#include <limits>
#include <iomanip>

const int arsize=20;
using namespace std;
struct emp
{
char name[arsize];
char phone[arsize];
float salary;
};
class Users
{
private:
//const int arsize=20;
int choice, num_of_names;
public:
Users();
void menu();
void enter(emp*pt, int n);
void print_all(emp*pt);
void print_condition(emp*pt);
void end_phone_array(emp*pt);
void bubble_sort(emp*pt);
void selection_sort(emp*pt);
void raise(emp*pt);
void file_store(emp*pt);
void file_read(emp*pt);

};
#endif USERS_H_

Вот необходимые части из исходного файла, который я считаю:

void Users::enter(emp*pt, int n)
{
extern int gl,count,f;
if(gl+n>10)
{
cout<<"Memory Full!\n";
}
else
{
for (int i=count;i<f+n;i++)
{
gl++;
cout<<"Enter user #"<<i+1<< " name(no more than 20 characters)\n";
cin.get();
cin.getline(pt[i].name, arsize);//.get();
cout<<"Enter user #"<<i+1<< " phone #\n";
cin.getline(pt[i].phone, arsize);//.get();
cout<<"Enter user #"<<i+1<< " salary\n";
(cin>>pt[i].salary);//.get();
}
count=gl;
f=gl;
}
}
void Users::file_store(emp* pt)
{
//ifstream::pos_type size;
extern int gl;
//float test;
//ofstream Testfile ("C:\\Users\\Ian\\Desktop\\Programming\\C++\\data.bin", ios::out| ios::binary);  //for personal computer use
ofstream Testfile ("data.bin", ios::out | ios::binary);
for (int i=0; i<gl;i++)
{
Testfile.write((char*)&pt[i].name, sizeof(pt));
Testfile.write(pt[i].phone, sizeof(pt[i].phone));
Testfile.write((char *)&pt[i].salary, sizeof(pt[i].salary));
}
}
void Users::file_read(emp*pt)
{
//extern int gl;
struct TEST
{
char n_array[20];
char p_array[13];
float salary;
};
TEST test[20];
for (int i=0;i<20;i++)
{
test[i].n_array[0]='\0';
test[i].p_array[0]='\0';
test[i].salary=0.0;
}
/*ifstream::pos_type size;
* char *memblocktest;*/
ifstream test_in ("data.bin", ios::in | ios::binary);
for(int i=0;i<10;i++)
{
if(test_in.is_open())for(int i=0;i<10;i++)
{
test_in.read((char*)&test, sizeof(test));
cout<<test[i].n_array<<"\n";
cout<<test[i].p_array<<endl;
cout<<"$"<<test[i].salary<<endl;
}
else
cout<<"Don't know what I am doing!\n";
}}

а вот и главный файл

#include "stdafx.h"#include "users.h"#include <iostream>
#include <cctype>
#include <limits>
#include <iomanip>
#include <cstring>
using namespace std;extern int gl=0, count =0, f=0;
int main()
{
Users Test;
std::cout.setf(std::ios::fixed);
std::cout.precision(2);
emp*test=new emp[10];
Test.menu();
int choice, num_of_names;
while(1)
{
if(!(cin>>choice))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout<<"ERROR!\n";
}
else
break;
}
while(choice!=9)
{
switch(choice)
{
case 1:{cout<<"How many users will you enter?\n";
cin>>num_of_names;
Test.enter(test, num_of_names);
Test.end_phone_array(test);
break;}
case 2:{Test.print_all(test);
break;}
case 3:{Test.print_condition(test);
break;}
case 4:{Test.bubble_sort(test);
break;}
case 5:{Test.selection_sort(test);
break;}
case 6:{Test.raise(test);
break;}
case 7:{Test.file_store(test);
break;}
case 8:{Test.file_read(test);
break;}
default:{"Bad Choice..........\n";
break;}
}
Test.menu();
while(1)
{
if(!(cin>>choice))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout<<"ERROR!\n";
}
else
break;
}
}
delete [] test;
//system("Pause");
return 0;
}

Я думаю, что есть много вещей, которые я мог бы улучшить, но сейчас я хотел бы разобраться с двоичной частью. Любые намеки очень ценятся. Спасибо!

0

Решение

Это выглядит неправильно:

void Users::file_store(emp* pt)
{
// etc...

Testfile.write((char*)&pt[i].name, sizeof(pt));
Testfile.write(pt[i].phone, sizeof(pt[i].phone));
Testfile.write((char *)&pt[i].salary, sizeof(pt[i].salary));

В первой строке вы сохраняете поле имени, но вы используете sizeof(pt) как размер, где размер на самом деле является размером значения указателя. Вы также берете адрес массива имен ( char**) и приведение его в char*

Чинить:

Testfile.write(pt[i].name, sizeof(pt[i].name));
Testfile.write(pt[i].phone, sizeof(pt[i].phone));
Testfile.write((char *)&pt[i].salary, sizeof(pt[i].salary));

На самом деле, вам может не потребоваться заполнять эти поля индивидуально (если только вы не пытаетесь соответствовать порядку, отличному от структуры), поскольку структура не имеет динамических данных. Вы можете сохранить всю запись в одном хите:

Testfile.write((char*)&pt[i], sizeof(struct emp));

Более того, вы можете хранить весь массив одним ударом и избежать зацикливания:

Testfile.write((char*)pt, gl * sizeof(struct emp));

Аналогично для чтения … Обратите внимание, что вы можете сохранить значение gl в файле тоже, так что вы знаете, сколько записей он содержит. Или, если вы хотите быть немного более загадочным, вы можете проверить размер файла и разделить sizeof(struct emp) в него, чтобы вывести количество записей.

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector