I am learning how to work with objects but am stuck the closest answer is could find was Read class objects from file c++.
In this question:
How would you go about the same task if your member variables were declared as private?
Try something similar to this:
Content of person.txt
John California 3683893
Stalin Russia 489895
Sample code:
#include<iostream>
#include <fstream>
#include <vector>
#include <string>
class person
{
private:
std::string _name;
std::string _address;
unsigned int _phone;
public:
person(const std::string& name, const std::string& address, unsigned int phone)
:_name(name),_address(address),_phone(phone)
{}
std::string getName() const { return _name; }
std::string getAddress() const { return _address; }
unsigned int getPhone() { return _phone; }
};
int main()
{
std::vector<person> persons;
std::string name;
std::string address;
unsigned int phone;
std::ifstream fs;
fs.open("person.txt");
if (fs.is_open()) {
while (std::getline(fs, name, ' ') && std::getline(fs, address, ' ') &&
(fs >> phone))
{
persons.push_back(person(name,address,phone));
}
}
for (auto p : persons) {
std::cout << p.getName() << " " << p.getAddress() << " " << p.getPhone() << '\n';
}
return 0;
}
Related
I have some data in the file that I would like to be able to read into a vector of a class-type/object. This object also has within itself a vector that takes in another class type, and the data that needs to populate that inner vector is also contained within the text file. How can I read the data from the file into the vectors accordingly without using getLine()?
The data is formatted as so in the document.
143 Jones
1234 2 C
-1
123 Smith
4321 4 A
132 3 B
-1
Where the first line is the ID of the student followed by their name, and below it is a series of classes that student has taken followed by the number of credits each course is worth and the grade the student got for the course.
Below is the course class header code
#pragma once
#include <iostream>
class Course {
public:
Course(int, int, std::string);
int getCourseCode() const {return courseCode;}
int getCredits() const {return courseCredits;}
std::string getGrade() const {return grade;}
void print(std::ostream &os) const;
private:
int courseCode;
int courseCredits;
std::string grade;
};
inline std::ostream &operator <<(std::ostream &os, const Course &course) {
course.print(os);
return os;
}
inline Course::Course(int courseCode, int courseCredits, std::string grade) {
this->courseCode = courseCode;
this->courseCredits = courseCredits;
this->grade = grade;
}
Below is the student class header code
#pragma once
#include <vector>
#include "course.h"
class Student {
public:
Student(int, std::string, std::vector<Course> courses);
int getID() const;
double getGPA() const;
std::string getName() const;
void print(std::ostream &os) const;
std::vector<Course> courses;
private:
int id;
std::string name;
};
inline std::ostream &operator << (std::ostream &os, const Student &student) {
student.print(os);
return os;
}
Below is the student.cpp code
#include "student.h"
#include <string>
using namespace std;
Student::Student(int id, std::string name, vector<Course> courses) {
this->id = id;
this->name = name;
this->courses = courses;
}
int Student::getID() const {
return id;
}
string Student::getName() const {
return name;
}
double Student::getGPA() const {
double total;
double creds;
double cgrade;
double gpa;
for(int i = 0; i < courses.size(); i++) {
if(courses[i].getGrade() == "A") cgrade = 4.0;
else if(courses[i].getGrade() == "B") cgrade = 3.0;
else if(courses[i].getGrade() == "C") cgrade = 2.0;
else if(courses[i].getGrade() == "D")cgrade = 1.0;
total += cgrade * courses[i].getCredits();
creds += courses[i].getCredits();
}
gpa = total / creds;
return gpa;
}
void Student::print(std::ostream &os) const {
os << id << " " << name << ": " << this->getGPA() << endl;
for(int i = 0; i < courses.size(); i++) {
os << courses[i];
}
}
This is what I've tried so far in terms of trying to load the vectors
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "student.h"
using namespace std;
void loadStudents(string fileName, vector<Student> &students);
bool compareCourses(const Course &c1, const Course &c2);
bool compareStudents(const Student &s1, const Student &s2);
void printResults(string fileName, vector<Student> &students);
int main() {
try {
vector<Student> students;
loadStudents("students.data", students);
cout << students.size() << " records processed" << endl;
return 0;
}
catch(string message) {
cout << "Error: " << message << endl;
exit(1);
}
};
void loadStudents(string fileName, vector<Student> &students) {
ifstream studentsFile(fileName.c_str());
if(!studentsFile.good()) {
throw string("Input file: " + fileName + ", not found!");
}
int id;
string name;
vector<Course> cs;
while(studentsFile >> id >> name >> cs) {
students.place_back(student);
}
studentsFile.close();
}
bool compareCourses(const Course &c1, const Course &c2) {
return c1.getGrade() < c2.getGrade();
}
bool compareStudents(const Student &s1, const Student &s2) {
return s1.getGPA() < s2.getGPA();
}
void printResults(string fileName, vector<Student> &students) {
ofstream outputFile(fileName.c_str());
if(!outputFile.good()) {
throw string("Output file: " + fileName + ", not found!");
}
for(auto student : students) {
outputFile << student.print(outputFile) << endl;
}
outputFile.close();
}
I'm getting an error stating that "no operator ">>" matches these operands" in the while loop inside the loadStudents function, which I think pertains to the istream for the vector.
The desired output is something like this printed to an output file.
143 Smith: 3.57143
4321 (4 credits): A
132 (3 credits): B
143 Jones: 2
1234 (2 credits): C
2 records processed
Where the student ID and name are printed along with their calculated GPA and the courses they took below them followed by a message stating the number of students that were processed.
My main issue pertains to the loading of the students vector with the subsequent data of the course information being appropriately loaded into the courses vector for each student. Is this possible without using the getLine() method and istream >>?
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'mm getting a bit confused why this isn't printing the name!
I've got a human.cpp :
#include <string>
#include <iostream>
#include "human.h"
human::human(int age, human *n){
m_age=age;
name = new char[2];
human::~human() = default;
void human::printDetails(){
std::cout <<"name is " << name << " age is " << m_age << std::endl;
}
and human.h:
class human {
public: //: needed
human(int age, human *name);
~human();
void printDetails();
private :
char *name;
int m_age;
};
and finally the main.cpp:
#include <iostream>
#include <string>
#include "human.h"
int main()
{
human *Alex = new human(10, Alex); //pointer // needs argument //should have both age and name
Alex->printDetails(); //print not Print
}
So my issue is: it prints the age, but does not print the name? Any suggestions? Thanks :)
There is no need for any new in your code. Since you #included <string> in your code I assume you want to use it:
#include <string>
#include <iostream>
class Person
{
int age;
std::string name;
public:
Person(int age, std::string name)
: age { age },
name { name }
{}
int get_age() const { return age; }
std::string const& get_name() const { return name; }
void print_details() const {
std::cout << "My name is " << name << ". I am " << age << " years old.\n";
}
};
int main()
{
Person p{ 19, "Alex" };
p.print_details();
}
If you *really* want to do it the hard waytm:
#include <cstring> // std::strlen()
#include <utility> // std::exchange(), std::swap()
#include <iostream>
class Person
{
char *name_;
int age_;
public:
Person(int age, char const *name) // constructor
// we don't want to call std::strlen() on a nullptr
// instead allocate just one char and set it '\0'.
: name_ { new char[name ? std::strlen(name) + 1 : 1]{} },
age_ { age }
{
if (name)
std::strcpy(name_, name);
}
Person(Person const &other) // copy-constructor
: name_ { new char[std::strlen(other.name_) + 1] },
age_ { other.age_ }
{
std::strcpy(name_, other.name_);
}
Person(Person &&other) noexcept // move-constructor
: name_ { std::exchange(other.name_, nullptr) }, // since other will be
age_ { other.age_ } // wasted anyway, we
{} // "steal" its resource
Person& operator=(Person other) noexcept // copy-assignment operator
{ // since the parameter other got
std::swap(name_, other.name_); // copied and will be destructed
age_ = other.age_; // at the end of the function we
return *this; // can simply swap the pointers
} // - know as the copy&swap idiom.
~Person() { delete[] name_; } // destructor
void print_details() const
{
std::cout << "I am " << name_ << ". I am " << age_ << " years old.\n";
}
};
int main()
{
Person p{ 19, "Alex" };
p.print_details();
}
If you don't want to implement the special member functions you'd have to = delete; them so the compiler-generated versions - which won't work correctly for classes managing their own resources - won't get called by accident.
#include <iostream>
#include <cstring>
#include <new>
using namespace std;
class human {
public:
human(int age, const char * name)
{
m_age=age;
m_name = new char[strlen(name)+1];
strcpy(m_name,name);
}
~human()
{
delete[] m_name;
}
void printDetails()
{
std::cout <<"name is " << m_name << " age is " << m_age << std::endl;
}
private :
char *m_name;
int m_age;
};
int main()
{
human *Alex = new human(10, "alex"); //pointer // needs argument //should have both age and name
Alex->printDetails(); //print not Print
delete Alex;
return 0;
}
You need to read more. The example you shared was wrong at many level, also read about dynamic memory management.
I guess you're confused with the second parameter of the human constructor. Look at this changes:
human.h
class human {
public:
human(int age, char *name);
human(const human& h);
human& operator=(const human& h);
void printDetails();
virtual ~human();
private:
int age;
char *name;
};
human.cpp
human::human(int _age, char *_name) {
age = _age;
name = new char[strlen(_name)+1];
strcpy(name, _name);
}
human::human(const human& _h) { //Copy constructor
age = _h.age;
name = new char[strlen(_h.name)+1];
strcpy(name, _h.name);
}
human& human::operator=(const human& _h) { //Copy assignment operator
age = _h.age;
name = new char[strlen(_h.name)+1];
strcpy(name, _h.name);
return *this;
}
void human::printDetails(){
std::cout <<"name is " << name << " age is " << age << std::endl;
}
human::~human() { //Destructor
delete[] name;
}
main.cpp
int main() {
human *alex = new human(10, "Alex");
alex->printDetails();
human *anotherAlex = new human(*alex);
anotherAlex->printDetails();
delete alex;
delete anotherAlex;
}
A suggestions: I would use Human as the class names and alex for the variable names. (See how I capitalized them)
For beginner you may use std::string, so you already included it. ))
human.h
#include <string>
class human
{
public: //: needed
human(int age, std::string name);
void printDetails();
private :
std::string name;
int m_age;
};
human.cpp
#include <iostream>
#include "human.h"
human::human(int age, std::string n)
{
m_age = age;
name = n;
}
void human::printDetails()
{
std::cout <<"name is: " << name << " age is: " << m_age << std::endl;
}
main.cpp
#include "human.h"
int main()
{
human *Alex = new human(10, "Alex");
Alex->printDetails();
}
I am new to C++ and am having issues when running this code, I have no idea where I have gone wrong.
I am just trying to make a simple Song class, then add and display an instance of the song object.
The error is saying that allot of my Methods are already defined in projectName.obj. I am also getting unresolved external symbol on IDSeed.
I am using visual studio 2017.
Main
#include "stdafx.h"
#include "Song.h"
#include "Song.cpp"
int main()
{
Song testSong("Evil Tram", "Catz N dogz");
testSong.setGenre("Tech House");
testSong.display();
return 0;
}
Song.cpp
#include "stdafx.h"
#include "Song.h"
Song::Song()
{
m_title = "";
m_album = "";//change to class
m_artist = "";//change to class
m_genre = "";//change to enum
m_ID = 0;
IDSeed = 0;
}
Song::Song(string title, string artist)
{
m_title = title;
m_album = "No Album";
m_genre = "No Genre";
m_artist = artist;
IDSeed++;
m_ID = IDSeed;
}
string Song::getTitle() const
{
return m_title;
}
string Song::getAlbum() const
{
return m_album;
}
string Song::getArtist() const
{
return m_artist;
}
string Song::getGenre() const
{
return m_genre;
}
int Song::getID() const
{
return m_ID;
}
void Song::setTitle(string title)
{
m_title = title;
}
void Song::setAlbum(string album)
{
m_album = album;
}
void Song::setArtist(string artist)
{
m_artist = artist;
}
void Song::setGenre(string genre)
{
m_genre = genre;
}
void Song::setID(int id)
{
m_ID = id;
}
void Song::display() const
{
cout << m_title << ", " << m_album << ", "
<< m_artist << ", " << m_genre << endl;
}
Song::~Song()
{
}
ostream & operator<<(ostream & out, Song & s)
{
out << s.m_title << ", " << s.m_album << ", "
<< s.m_artist << ", " << s.m_genre << endl;
return out;
}
istream & operator>>(istream & in, Song & s)
{
in >> s.m_title >> s.m_album >> s.m_artist >> s.m_genre;
return in;
}
Song.h
#pragma once
#include <iostream>
#include <string>
#include <ostream>
using std::string;
using std::cout;
using std::endl;
using std::ostream;
using std::istream;
class Song
{
private:
#pragma region Variables
string m_title;
string m_album;//change to class
string m_artist;//change to class
string m_genre;//change to enum
int m_ID;
static int IDSeed;
#pragma endregion
public:
Song();
Song(string title, string artist);
#pragma region Getters
string getTitle() const;
string getAlbum()const;
string getArtist()const;
string getGenre()const;
int getID()const;
#pragma endregion
#pragma region Setters
void setTitle(string title);
void setAlbum(string album);
void setArtist(string artist);
void setGenre(string genre);
void setID(int id);
#pragma endregion
#pragma region Methods
void display() const;
#pragma endregion
friend ostream& operator<<(ostream& out,
Song& s);
friend istream& operator>>(istream& in,
Song& s);
~Song();//destructer
};
Solved by removing the #include song.cpp and placing the static keyword in the cpp file instead of the .h
Hello and thanks in advance for helping,
I've the problem that I don't see any output on my eclipse console (on linux ubuntu 12.04).
I have this little C++ program:
Addressverwaltung.cpp:
#include <iostream>
#include "Adresse.h"
using namespace std;
int main() {
cout << "asdf";
Adresse lAdresse1("Max", "Tester", "Strasse 21", 6423, "lol", "asdf#hotmail.com");
lAdresse1.printAdresse();
lAdresse1.setName("Testing");
lAdresse1.printAdresse();
return 0;
}
Adresse.h:
#ifndef Adresse_h
#define Adresse_h
#include <iostream>
#include <string>
class Adresse{
public:
Adresse(std::string pVorname, std::string pName);
Adresse(std::string pVorname, std::string pName, std::string pStrasse, int pPlz, std::string pOrt, std::string pEmail);
void printAdresse();
void setVorname(std::string pVorname);
void setName(std::string pName);
std::string getName();
private:
std::string mVorname;
std::string mName;
std::string mStrasse;
int mPlz;
std::string mOrt;
std::string mEmail;
};
#endif
Adresse.cpp:
#include "Adresse.h"
Adresse::Adresse(std::string pVorname, std::string pName){
mVorname = pVorname;
mName = pName;
}
Adresse::Adresse(std::string pVorname, std::string pName, std::string pStrasse, int pPlz, std::string pOrt, std::string pEmail){
mVorname = pVorname;
mName = pName;
mStrasse = pStrasse;
mPlz = pPlz;
mOrt = pOrt;
mEmail = pEmail;
}
void Adresse::printAdresse(){
std::cout << "ADRESSE:";
std::cout << mVorname + mName;
std::cout << "STRASSE: " + mStrasse;
std::cout << "PLZ: " + mPlz;
std::cout << "EMAIL: " + mEmail;
}
void Adresse::setVorname(std::string pVorname){
mVorname = pVorname;
}
void Adresse::setName(std::string pName){
mName = pName;
}
std::string Adresse::getName(){
return mName;
}
Whenever I click "run" I see the message "make all
make: Nothing to be done for `all'." for about 4 seconds, afterwards the console is empty. I tried cleaning and rebuilding the project but that doesn't help.
Does anyone know how to fix this?
Put a cout.flush() before the return in main() function. That should help:
int main() {
cout << "asdf";
Adresse lAdresse1("Max", "Tester", "Strasse 21", 6423, "lol", "asdf#hotmail.com");
lAdresse1.printAdresse();
lAdresse1.setName("Testing");
lAdresse1.printAdresse();
cout.flush(); // <<<<<<<<<<<<<<<<<<<<<<<<
return 0;
}
I have an issue where I am reading a line from a file using getline and the using a stringstream to separate the different variables using a comma as a delimiter. The issue is that a standard cout of the variables shows the seatDes properly, but using the vector I get the name back instead of the seatDes. Not sure why this is happening.
A standard line in file: Jane Doe,04202013,602,1A
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <cstdlib>
#include "reservation.h"
int main(int argc, char **argv)
{
std::ifstream flightFile;
std::string name, date, seatDes, flightNum, line;
int error = 0, conFlightNum;
flightFile.open("reservations.txt");
if(!flightFile)
{
//returns a error value if there is a problem reading the file
error = 1;
return error;
}
else
{
//Start reading files and sticks them into a class object and sticks the object into the vector set
while (std::getline(flightFile, line))
{
std::istringstream ss(line);
std::getline(ss, name, ',');
std::getline(ss, date, ',');
std::getline(ss, flightNum, ',');
conFlightNum = atoi(flightNum.c_str());
ss >> seatDes;
reservation newRes(name, date, conFlightNum, seatDes);
std::cout << name << std::endl << date << std::endl << conFlightNum << std::endl << seatDes << std::endl;
std::cout << "Vector Component" << std::endl;
std::cout //<< newRes.getName() << std::endl << newRes.getDate() << std::endl << newRes.getFlightNum()
<< std::endl << newRes.getSeatDesg() << std::endl;
}
}
flightFile.close();
return 0;
}
reservation.h file
class reservation {
private:
std::string name, seatDesg, date;
int flightNum;
public:
//Default Constructor
reservation(){}
//Big Constructor
reservation(std::string name, std::string date, int flightNum, std::string seatDesg)
{
this->name = name;
this->seatDesg = name;
this->date = date;
this->flightNum = flightNum;
}
//Setters
void setName(std::string name)
{ this->name = name; }
void setFlightNum(int flightNum)
{ this->flightNum = flightNum; }
void setSeatDesg(std::string seatDesg)
{ this->seatDesg = seatDesg; }
void setDate(std::string date)
{ this->date = date; }
//Getters
std::string getName()
{ return name; }
std::string getSeatDesg()
{ return seatDesg; }
std::string getDate()
{ return date; }
int getFlightNum()
{ return flightNum; }
};
reservation(std::string name, std::string date, int flightNum, std::string seatDesg)
{
this->name = name;
this->seatDesg = name; // Here is your problem
this->date = date;
this->flightNum = flightNum;
}
Should be
this->seatDesg = seatDesg;