my code in below.
int main() {
Employee* employee = new Employee();
cout << "Creating File..." << endl;
fstream file("deneme1.txt",ios::out|ios::binary|ios::ate);
for(int i=0;i<10;i++){
if(i<4){
string name;
float salary;
int yearHired;
cout<<"Enter Name: ";
cin>>name;
cout<<"Enter Salary: ";
cin>>salary;
cout<<"Enter Year Hired: ";
cin>>yearHired;
employee->set_id(i);
employee->set_name(name);
employee->set_salary(salary);
employee->set_yearHired(yearHired);
file.write((char*)&employee,sizeof(employee));
file.close();
}
}
file.open("deneme1.txt",ios::in|ios::out|ios::binary);
file.seekg(0);
while((file.read((char*)&employee,sizeof(employee)))) {
cout << employee->get_id();
}
}
I have binary file named "deneme1.txt". I record four object to "deneme1.txt". I want to get all line of "deneme1.txt" in while loops, but I can only get the last line.(So output is
"Creating File...
3"
)
How can I get all the line in the file? Maybe the file has only one object?
my class in below
class Employee
{
private:
string name;
int id;
float salary;
int yearHired;
public:
void set_name(string n)
{
this->name = n;
}
void set_id(int i)
{
this->id = i;
}
string get_name()
{
return name;
}
int get_id()
{
return id;
}
void set_salary(float s)
{
this->salary = s;
}
float get_salary()
{
return salary;
}
void set_yearHired(int y)
{
this->yearHired = y;
}
int get_yearHired()
{
return yearHired;
}
};
I expect that output be "0 1 2 3"
After some cleanup, this should not have any undefined behavior.
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
class Employee {
private:
std::string name;
int id;
float salary;
int yearHired;
public:
Employee(const std::string &name, int id, float salary, int yearHired) : name(name), id(id), salary(salary),
yearHired(yearHired) {}
Employee(Employee const&) = delete;
Employee& operator=(Employee const&) = delete;
int get_id() const {
return id;
}
};
int main() {
std::cout << "Creating File..." << std::endl;
{
std::ofstream file("deneme1.txt", std::ios::out | std::ios::binary | std::ios::ate);
std::string name;
for (int i = 0; i < 4; i++) {
float salary;
int yearHired;
std::cout << "Enter Name: ";
std::cin >> name;
std::cout << "Enter Salary: ";
std::cin >> salary;
std::cout << "Enter Year Hired: ";
std::cin >> yearHired;
Employee employee(name, i, salary, yearHired);
file.write((char *) &employee, sizeof(employee));
}
} // file.close();
std::ifstream file("deneme1.txt", std::ios::in | std::ios::binary);
char* employeeData = new char[sizeof(Employee)];
{
const Employee &employee = *reinterpret_cast<const Employee *>(employeeData);
while ((file.read((char *) &employee, sizeof(employee)))) {
std::cout << employee.get_id();
}
}
delete[]employeeData;
return EXIT_SUCCESS;
}
Related
I tried the below code to write an object to a dat file:
#include<iostream>
#include<fstream>
#include<string>
#include<string.h>
using namespace std;
class Student
{ //data members
int adm;
string name;
public:
Student()
{
adm = 0;
name = "";
}
Student(int a,string n)
{
adm = a;
name = n;
}
Student setData(Student st) //member function
{
cout << "\nEnter admission no. ";
cin >> adm;
cout << "Enter name of student ";
cin.ignore();
getline(cin,name);
st = Student(adm,name);
return st;
}
void showData()
{
cout << "\nAdmission no. : " << adm;
cout << "\nStudent Name : " << name;
}
int retAdmno()
{
return adm;
}
};
/*
* function to write in a binary file.
*/
void demo()
{
ofstream f;
f.open("student.dat",ios::binary);
for(int i = 0;i<4;i++)
{
Student st;
st = st.setData(st);
f.write((char*)&st,sizeof(st));
}
f.close();
ifstream fin;
fin.open("student.dat",ios::binary);
Student st;
while(!fin.eof())
{
fin.read((char*)&st,sizeof(st));
st.showData();
}
}
int main()
{
demo();
return 0;
}
But when I am executing the demo function I am getting some garbage values from the "student.dat"
file. I am creating a database and want to get the records but I am not able to get all the records in the dat file.
Please suggest a solution
You cannot write complex data types to a file in binary mode. They have some additional variables and functions inside,which you do not know or see. Those data types have some internal state that or context dependent. So, you cannot store in binary and then reuse it somewhere else. That will never work.
The solution is serialization/deserialization.
This sounds complicated, but is not at all in your case. It basically means that all your data from your struct shall be converted to plain text and put in a text-file.
For readin the data back, it will be first read as text, and then converted to your internal data structures.
And the default approach for that is to overwrite the inserter << operator and extractor >> operator.
See the simple example in your modified code:
#include<iostream>
#include<fstream>
#include<string>
#include<iomanip>
class Student
{ //data members
int adm;
std::string name;
public:
Student()
{
adm = 0;
name = "";
}
Student(int a, std::string n)
{
adm = a;
name = n;
}
Student setData(Student st) //member function
{
std::cout << "\nEnter admission no. ";
std::cin >> adm;
std::cout << "Enter name of student ";
std::getline(std::cin>> std::ws, name);
st = Student(adm, name);
return st;
}
void showData()
{
std::cout << "\nAdmission no. : " << adm;
std::cout << "\nStudent Name : " << name;
}
int retAdmno()
{
return adm;
}
friend std::ostream& operator << (std::ostream& os, const Student& s) {
return os << s.adm << '\n' << s.name << '\n';
}
friend std::istream& operator >> (std::istream& is, Student& s) {
return std::getline(is >> s.adm >> std::ws, s.name);
}
};
/*
* function to write in a binary file.
*/
void demo()
{
std::ofstream f("student.dat");
for (int i = 0; i < 4; i++)
{
Student st;
st = st.setData(st);
f << st;
}
f.close();
std::ifstream fin("student.dat");
Student st;
while (!fin.eof())
{
fin >> st;
st.showData();
}
}
int main()
{
demo();
return 0;
}
Throwing this out there first I'm a still learning how to program in school. I'm having an issue reading in to a dynamically created array with a pointer to one of my classes. The function readClassArray() isn't getting the variable back from student.getCreditNumber. The program complies fine in Visual Studio but when I get the the readClassArray it just skips over the function because s.getCreditNumber returns 0.
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
using namespace std;
class Courses{
private:
int courseNumber;
double hours;
string courseName;
char grade;
public:
void setCourseNumber(int n){courseNumber = n; }
void setCreditHours(double c) { hours = c; }
void setCourseName(string n) { courseName = n; }
void setGrade(char g) { grade = g; }
int getCourseNumber() { return courseNumber; }
double getCreditHours() { return hours; }
string getCourseName() { return courseName; }
char getGrade() { return grade; }
};
class Student : public Courses{
private:
string firstName;
string lastName;
string studentNumber;
int creditNumber;
double gpa;
public:
Courses * courses;
Student() {
firstName = " ";
lastName = " ";
studentNumber = " ";
creditNumber = 0;
gpa = 0.0;
courses = NULL;
}
~Student() {
delete[] courses;
};
void setFirstName(string n) { firstName = n; }
void setLastName(string l) { lastName = l; }
void setStudentNumber(string a) { studentNumber = a; }
void setCreditNumber(int num) { creditNumber = num; }
string getFirstName() { return firstName; }
string getLastName() { return lastName; }
string getStudentNumber() { return studentNumber; }
int getCreditNumber() { return creditNumber; }
};
#endif
Student.cpp
#include "Student.h"
#include <iostream>
#include <string>
using namespace std;
void readStudent();
void readCourseArray();
void computeGPA();
void printSummary();
void readStudent() {
Student a;
string number;
string firstName;
string lastName;
int courses;
cout << "Enter student number: ";
cin >> number;
a.setStudentNumber(number);
cout << "Enter student first name: ";
cin >> firstName;
a.setFirstName(firstName);
cout << "Enter student last name: ";
cin >> lastName;
a.setLastName(lastName);
cout << "Enter student number of courses: ";
cin >> courses;
a.setCreditNumber(courses);
cout << "\n"; }
void readCourseArray(){
Student s;
s.courses = new Courses[s.getCreditNumber()];
int num;
double cHours;
string cName;
char grade;
cout << "test" << endl;
for (int i = 0; i < s.getCreditNumber(); i++){
cout << "Enter class " << i + 1 << " number: ";
cin >> num;
s.courses[i].setCourseNumber(num);
cout << "Enter class " << i + 1 << " name: ";
cin >> cName;
s.courses[i].setCourseName(cName);
cout << "Enter class " << i + 1 << " hours: ";
cin >> cHours;
s.courses[i].setCreditHours(cHours);
cout << "Enter class " << i + 1 << " grade: ";
cin >> grade;
s.courses[i].setGrade(grade);
cout << "\n";
}
}
At the start of readCourseArray you've created s. When that happens the value of the creditNumber member is 0 as set by the default constructor. You need to do something to set it to a non-zero value. If you're expecting the value set in readStudent to carry over you need to plumb the two functions together. Either pass in a Student object as a reference to each function, or have readStudent return a Student object and pass that to readCourseArray.
I have recently tried to learn how to create an object of vectors in order to represent objects of students including their names and grades. but when I wrote my program I got some errors regarding using &. I do not know what is the problem with my errors. could you please help me to fix it?
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void printvector(const vector< student>&); // fill vector.fill in student information
void fillvector(vector< student>&); // print the information of all students
class student {
public:
student();
student(string, char);
~student();
string getName() ;
char getGrade() ;
void setName(string);
void setGrade(char);
private:
string newName;
char newGrade;
};
student::student() { newGrade = ' '; }
student::student(string name, char grade) {
newName = name;
newGrade = grade;
}
student::~student(){ }
string student::getName() { return newName; }
char student::getGrade() { return newGrade; }
void student::setName(string name) { newName = name; }
void student::setGrade(char grade) { newGrade = grade; }
int main() {
vector<student> myclass;
printvector(myclass);
fillvector(myclass);
return 0;
}
void fillvector(vector< student>& newmyclass) {
string name;
char grade;
int classsize;
cout << "how many students are in your class?";
cin >> classsize;
for (int i = 0; i < classsize; i++) {
cout << "enter student name";
cin >> name;
cout << "enter student grade";
cin >> grade;
student newstudent(name, grade);
newmyclass.push_back(newstudent);
cout << endl;
}
}
void printvector( vector< student>& newmyclass) {
unsigned int size = newmyclass.size();
for (unsigned int i = 0; i < size; i++) {
cout << "student name:" << newmyclass[i].getName() << endl;
cout << endl;
cout << "student grade" << newmyclass[i].getGrade() << endl;
cout << endl;
}
}
It seems you're printing your vector before filling it.. Is your problem fixed when you swap them around?
int main() {
vector<student> myclass;
printvector(myclass); // <--- These two lines should probably be swapped
fillvector(myclass); // <---
return 0;
}
I wish to output different string for reading variables. For example, below, I wish to print Enter english marks before reading english marks using eng.setmarks(). Please suggest a way to implement this.
Here is my code: (look at for loop below)
#include <iostream>
#include <cstring>
using std::cin;
using std::cout;
class student {
char name[20];
int age;
class marks {
int marks;
public:
void setmarks( int x) {
marks = x;
}
int getmarks() {
return marks;
}
};
public:
marks eng, math, phy, chem, cs; // nested objects are public
void setname( char* n) {
strncpy( name, n, 20);
}
char* getname() {
return name;
}
void setage( int a) {
age = a;
}
float total() {
size_t total = eng.getmarks() + math.getmarks() +
phy.getmarks() + chem.getmarks() + cs.getmarks();
return total/500.0;
}
};
int main() {a
student new_stud;
char temp[20];
cout << "Enter name: ";
cin >> temp;
cin.get( temp, sizeof(temp));
new_stud.setname(temp);
int age;
cout << "Enter age: ";
cin >> age;
new_stud.setage( age);
for( size_t i = 0; i < 5; ++i) {
// I wish to output: "Enter marks in" + subject_name, but harcoding it seems tedious
}
cout << "\nTotal Percentage: " << new_stud.total();
return 0;
}
So if I understand correctly, you would like to print out the name of the variable which you are about to read into. Now this can't be done on the way you want it. The best thing you can do is make an array of subject names, and an array of marks.
string[5] Subjects = {"Maths", "English", "Chemistry", "Physiscs", "Computer Sciences"};
marks[5] Marks;
for(int i=0;i<5;i++) {
cout << "Please enter marks in " << Subjects[i] << ":" << endl;
int a;
cin >> a;
Marks[i].setmarks(a);
}
You could also make the marks class have a field subject name, and give it a function inputfromuser(), like this:
class marks {
int marks;
string subjectName;
public:
void setmarks( int x) {
marks = x;
}
int getmarks() {
return marks;
}
void inputfromuser() {
cout << "Please enter marks in " << subjectName << ":" << endl;
cin >> marks;
}
};
Sorry for me using the std::string type, I am not very comfortable with the raw char[] way to handle texts.
class Student
{
private:
string name;
int year;
string semester;
int AmtClass;
static string Year[4];
public:
Student();
Student(int AmtClass);
Student(Student &);
void setName(string name);
void setYear(int year);
void setSemester(string semester);
void setAmtClass(int AmtClass);
string getName();
int getYear();
string getSemester();
int getAmtClass();
~Student()
{
if(AmtClass > 0)
delete [] course;
}
};
string Student::Year[4] = { "Freshman", "Sophomore", "Junior", "senior" };
Student::Student()
{
name = "";
year = 0;
semester = "";
AmtClass = 0;
}
Student::Student(int amount)
{
AmtClass = amount;
string *pName;
pName = new string[AmtClass];
for(int i = 0; i < AmtClass; i++)
{
pName[i] = "";
}
}
Skipping Accessors and Mutator functions...
void readStudentData(Student &);
void printStudentData(Student);
int main()
{
int amount;
cout << "How many courses are you currently taking? ";
cin >> amount;
Student kid;
kid.setAmtClass(amount);
readStudentData(kid);
}
void readStudentData(Student &kid)
{
cin.ignore(10000, '\n');
int amount = kid.getAmtClass();
string name = "";
string semester = "";
int year = 0;
cout << "What is your full name? ";
getline(cin,name);
cout << "\nHow many years have you been in college? ";
cin >> year;
cout << "\nWhat is your current semester? ";
getline(cin,semester);
Student kid1(amount);
cout << "Please enter the name of all your courses." << endl;
for(int i = 0; i < amount; i++)
{
cout << "Course #" << i+1 << " : ";
getline(cin,pName[i]);
}
}
Okay edited this program a bit after realizing my pName is a local variable in the constructor...I am supposed to create a constructor that received an integer parameter corresponding to the number of courses the student is taking.The function dynamically allocates the string array of courses and sets each element to "". And then I am supposed to use this to record the names of the courses the student is taking.
The Year array should simply be allocated to the amount, and that's it:
Student::Student(int amount)
: Year(new std::string[amount]()), AmtClass(amount)
{
}
You can also use std::vector for this so you do not have to deal with deleting the memory yourself:
class Student
{
std::vector<std::string> Year;
// ...
};
Student::Student(int amount)
: Year(amount), AmtClass(Year.size())
{
}