Compiles and everything except adding in a 'ship'
Constructor for ship
Ship::Ship(std::string name, int length, std::string show) {
std::string _name = name;
int _length = length;
std::string _show = show;
}
void Ships::buildShip() {
std::string name, show;
int length = 0;
std::cout << "What is the name of the ship? ";
std::cin >> name;
std::cout << "How long is the ship in feet? ";
std::cin >> length;
std::cout << "What show/movie is the ship from? ";
std::cin >> show;
std::cout << std::endl;
Ship ship(name, length, show);
addShip(ship);
}
void Ships::addShip(Ship &ship) {
ships.push_back(ship);
}
I'm sure it's something very obvious, I've searched the web and found nothing helpful. I only took snippets from my code if anything else is needed let me know. Thanks in advance!
/Ship.h
#pragma once
#include <string>
class Ship {
std::string _name;
int _length;
std::string _show;
public:
Ship(){
std::string name = _name;
int length = _length;
std::string show = _show;
};
Ship(std::string _name, int _length, std::string _show);
std::string getName();
int getLength();
std::string getShow();
};
/Ship.cpp
#include <string>
#include "Ship.h"
Ship::Ship(std::string name, int length, std::string show) {
std::string _name = name;
int _length = length;
std::string _show = show;
}
std::string Ship::getName() {
return _name;
}
int Ship::getLength() {
return _length;
}
std::string Ship::getShow() {
return _show;
}
/Ships.h
#pragma once
#include <vector>
#include "Ship.h"
class Ships {
std::vector<Ship> ships;
public:
void addShip(Ship &ship);
int getCount();
Ship getLongestShip();
void buildShip();
int getNumberOfShipsLongerThan(int input);
void displayShips();
};
/Ships.cpp
#include "Ships.h"
#include <iostream>
void Ships::addShip(Ship &ship) {
ships.push_back(ship);
}
int Ships::getCount() {
return ships.size();
}
Ship Ships::getLongestShip() {
Ship longestShip = ships[0];
for (Ship aShip : ships) {
if (longestShip.getLength() < aShip.getLength())
longestShip = aShip;
}
std::cout << "The longest ship is the " << longestShip.getName() << std::endl;
std::cout << "From end to end the length is " << longestShip.getLength() << std::endl;
std::cout << "The show/movie it is from is " << longestShip.getShow() << std::endl;
return longestShip;
}
int Ships::getNumberOfShipsLongerThan(int input) {
int longerThan = 0;
int size = ships.size();
for (int i = 0; i < size; i++) {
if (input < ships[i].getLength())
longerThan++;
}
return longerThan;
}
void Ships::displayShips() {
std::cout << " Complete Bay Manifest " << std::endl;
std::cout << "***********************" << std::endl;
for (int i = 0; i < ships.size(); i++) {
int a = i + 1;
std::cout << "Ship (" << a << ")" << std::endl;
std::cout << "Name: " << ships[i].getName() << std::endl;
std::cout << "Length: " << ships[i].getLength() << std::endl;
std::cout << "Show: " << ships[i].getShow() << std::endl<<std::endl;
}
}
void Ships::buildShip() {
std::string name, show;
int length = 0;
std::cout << "What is the name of the ship? ";
std::cin >> name;
std::cout << "How long is the ship in feet? ";
std::cin >> length;
std::cout << "What show/movie is the ship from? ";
std::cin >> show;
std::cout << std::endl;
Ship ship(name, length, show);
addShip(ship);
}
/driver.cpp
#include <iostream>
#include "Ship.h"
#include "Ships.h"
void menu();
Ship buildShip();
void shipsInBay(Ships &ships);
void processDirective(int choice, Ships &ships);
void longerThan(Ships &ships);
int main() {
std::cout << "Welcome to Daniel Mikos' Ship Bay!" << std::endl << std::endl;
menu();
system("PAUSE");
return 0;
}
void menu() {
Ships ships;
int choice = 0;
std::cout << "Please make a selection" << std::endl;
std::cout << " (1) Add a ship to the bay" << std::endl;
std::cout << " (2) How many ships are already in the bay?" << std::endl;
std::cout << " (3) Which ship is the longest? " << std::endl;
std::cout << " (4) Ships longer than ___? " << std::endl;
std::cout << " (5) Manifest of all ships currently logged" << std::endl;
std::cout << " (6) Exit" << std::endl;
std::cout << " Choice: ";
std::cin >> choice;
processDirective(choice, ships);
}
Ship buildShip() {
std::string name, show;
int length = 0;
std::cout << "What is the name of the ship? ";
std::cin >> name;
std::cout << "How long is the ship in feet? ";
std::cin >> length;
std::cout << "What show/movie is the ship from? ";
std::cin >> show;
std::cout << std::endl;
Ship ship(name, length, show);
return ship;
}
void shipsInBay(Ships &ships) {
int count = ships.getCount();
std::cout << std::endl;
std::cout << "There is currently " << count;
std::cout << " ship(s) in bay" << std::endl << std::endl;
}
void longerThan(Ships &ships) {
int input = 0;
std::cout << "Find ships longer than? ";
std::cin >> input;
std::cout << "There are " << ships.getNumberOfShipsLongerThan(input) << "longer than " << input << "feet";
}
void processDirective(int choice, Ships &ships) {
if (choice == 1)
buildShip();
if (choice == 2)
shipsInBay(ships);
if (choice == 3)
ships.getLongestShip();
if (choice == 4)
longerThan(ships);
if (choice == 5)
ships.displayShips();
menu();
}
There is all of my code
To add an object to a vector of objects use emplace_back() and pass the constructor arguments as arguments to emplace back. It will then build the object in place so call:
ships.emplace_back(name, length, show);
to construct your ship object in place. Your constructor also is incorrect as pointed out by #Kevin. You need to change it to:
this->_name = name;
this->_length = length;
this->_show = show;
assuming I've guessed your class design correctly.
EDIT
Tried to build a minimum example from this and this works fine for me:
Header.h
class Ship {
std::string _name;
int _length;
std::string _show;
public:
Ship();
Ship(std::string _name, int _length, std::string _show);
std::string getName();
int getLength();
std::string getShow();
};
class Ships {
public:
void addShip(Ship &ship);
void buildShip();
std::vector<Ship> ships;
};
and Source.cpp
#include "Header.h"
Ship::Ship(std::string name, int length, std::string show) {
this->_name = name;
this->_length = length;
this->_show = show;
}
void Ships::buildShip() {
std::string name = "Name";
std::string show = "Show";
int length = 0;
ships.emplace_back(name, length, show);
}
int main(int argc, char argv[])
{
Ships ships;
ships.buildShip();
std::cout << "Number of ships = " << ships.ships.size() << std::endl;
return 0;
}
Prints Number of ships = 1. Can you slim it down to something like this?
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
So, I am learning about classes in C++, I created two classes, one for a University that contains a list of class Students, i managed to create students, and introduce some values to the classes, but now i want to sort the class students by student number, i tryed using the sort function, but im not succeeding. I will leave my code bellow, please give some good tips and advises, so I can improve my code. thanks
main.css
#include <iostream>
#include "university.h"
#include "students.h"
using namespace std;
int main() {
university univ = university();
return 0;
}
university.h
#pragma once
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
#include "students.h"
using namespace std;
class university
{
private:
list<students> lstudents;
list<students>::iterator itstudents;
public:
university();
void setStudents(list<students> lstudents);
void registerStudent();
void list();
void average();
//void sortstudents();
};
university.cpp
#include "university.h"
using namespace std;
university::university() { //constructor
string resp = "s";
int op;
bool out = true;
cout << "Enter Students:" << endl;
while (resp != "n")
{
this->registerStudent();
cout << "Continue inserting? (s/n)" << endl;
cin >> out;
cin.ignore();
}
while (out)
{
cout << "What you Want to do? (1- List Students 2- Sudent Average 3- Sort Students by Number 4- Leave)" << endl;
cin >> op;
switch (op)
{
case 1:
this->list();
break;
case 2:
this->average();
break;
/*case 3:
this->sortStudents();
break;*/
case 4:
out = false;
break;
};
}
}
void university::setStudents(list<students> lstudents) {
this->lstudents = lstudents;
}
void university::registerStudent()
{
lstudents.push_back(students());
}
void university::list()
{
int sum = 0;
cout << "------------------------- LIST STUDENTS -------------------------------\n\n";
cout << left << setw(11) << "Number"
<< left << setw(30) << "Name"
<< left << setw(30) << "Course"
<< left << setw(10) << "Average";
cout << "\n";
for (itstudents = lstudents.begin(); itstudents != lstudents.end(); itstudents++)
{
(*itstudents).list();
++sum;
}
//cout << "Total de pacientes:" << somatorio << endl;
//somatorio = 0;
}
void university::average()
{
int sum = 0;
double average = 0;
for (itstudents = lstudents.begin(); itstudents != lstudents.end(); itstudents++)
{
average += (*itstudents).getaverage();
++sum;
}
cout << "Average:" << average / sum << endl;
}
//void university::sortstudents() {
// sort(lstudents.begin(), lstudents.end(), &students::compare);
//}
students.h
as you can see the commented code is my attempts on sorting the class student my number
#pragma once
#include <iomanip>
#include <algorithm>
#include <list>
#include "university.h"
using namespace std;
class students {
private:
std::string name;
std::string course;
int number;
double average;
public:
//friend bool operator<(estudantes& left,estudantes& right) { return left.matricula < right.matricula; };
students();
void list();
double getaverage();
int getnumber();
//bool compare(estudantes a, estudantes b);
};
students.cpp
#include "students.h"
students::students() {
cout << "Name: ";
getline(cin, name);
cout << "Course: ";
getline(cin, course);
cout << "Number: ";
cin >> this->number;
cout << "Average: ";
cin >> this->average;
}
void students::list() {
cout << left << setw(11) << number;
cout << left << setw(30) << name;
cout << left << setw(30) << course;
cout << left << setw(10) << average << endl;
}
double students::getaverage() {
return average;
}
int students::getnumber() {
return number;
}
//bool estudantes::compare(student a, student b) {
//
// if (a.number < b.number)
// return 1;
// else
// return 0;
//}
Made it selfcontained and fixed. I'll post and then aexplain as surely people will have closed the question too soon:
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <list>
#include <string>
class students {
private:
std::string name;
std::string course;
int number;
double average;
public:
// friend bool operator<(students& left,students& right) { return
// left.matricula < right.matricula; };
students();
void list();
double getaverage();
int getnumber();
static bool compare(students const& a, students const& b);
};
students::students()
{
std::cout << "Name: "; getline(std::cin, name);
std::cout << "Course: "; getline(std::cin, course);
std::cout << "Number: "; std::cin >> this->number;
std::cout << "Average: "; std::cin >> this->average;
}
void students::list() {
std::cout << std::left << std::setw(11) << number;
std::cout << std::left << std::setw(30) << name;
std::cout << std::left << std::setw(30) << course;
std::cout << std::left << std::setw(10) << average << std::endl;
}
double students::getaverage() {
return average;
}
int students::getnumber() {
return number;
}
bool students::compare(students const& a, students const& b) {
return a.number > b.number;
}
class university {
private:
std::list<students> lstudents;
std::list<students>::iterator itstudents;
public:
university();
void setStudents(std::list<students> lstudents);
void registerStudent();
void list();
void average();
void sortStudents();
};
university::university() // constructor
{
std::string resp = "s";
int op;
bool out = true;
std::cout << "Enter Students:" << std::endl;
while (resp != "n") {
this->registerStudent();
std::cout << "Continue inserting? (s/n)" << std::endl;
std::cin >> out;
std::cin.ignore();
}
while (out) {
std::cout << "What you Want to do? (1- List Students 2- Sudent Average "
"3- Sort Students by Number 4- Leave)"
<< std::endl;
std::cin >> op;
switch (op) {
case 1: this->list(); break;
case 2:
this->average();
break;
case 3: this->sortStudents(); break;
case 4: out = false; break;
};
}
}
void university::setStudents(std::list<students> lstudents) {
this->lstudents = lstudents;
}
void university::registerStudent()
{
lstudents.push_back(students());
}
void university::list()
{
int sum = 0;
std::cout << "------------------------- LIST STUDENTS -------------------------------\n\n";
std::cout << std::left << std::setw(11) << "Number"
<< std::left << std::setw(30) << "Name"
<< std::left << std::setw(30) << "Course"
<< std::left << std::setw(10) << "Average";
std::cout << "\n";
for (itstudents = lstudents.begin(); itstudents != lstudents.end(); itstudents++)
{
(*itstudents).list();
++sum;
}
//std::cout << "Total de pacientes:" << somatorio << std::endl;
//somatorio = 0;
}
void university::average()
{
int sum = 0;
double average = 0;
for (itstudents = lstudents.begin(); itstudents != lstudents.end(); itstudents++)
{
average += (*itstudents).getaverage();
++sum;
}
std::cout << "Average:" << average / sum << std::endl;
}
void university::sortStudents() {
lstudents.sort(&students::compare);
}
int main() {
university univ = university();
return 0;
}
Explanation
There were a number of issues.
students::compare was a non-static member function, meaning it can only be called on an instance of student. To have a 2-argument sort predicate as required, simply making it static can work
The implementation could be much more idiomatic:
bool students::compare(students const& a, students const& b) {
return a.number > b.number;
}
That avoids the C-ism of using 1 as if it were true, and the useless if/else
You used std::sort but it requires random access iterators. std::list doesn't provide that. For that reason std::list::sort exists:
void university::sortStudents() {
lstudents.sort(&students::compare);
}
Among many other style issues:
don't using namespace std;
don't do side-effects in constructors?
error-check IO
avoid division by zero (e.g. in average()
I recently started with file structuring in C++ with little success. The project was split into following files
-groups.h
-groups.cpp
-people.h
-people.cpp
-main.cpp
There are 2 base classes, groups and players and every other class in inherited by either of them.
Here's the files
groups.h
people.h
groups.cpp
people.cpp
main.cpp
groups.h
#ifndef GROUPS_H
#define GROUPS_H
//Groups of people one of the base classes
class groups {
int num_of_people;
float avg_age;
friend class SoccerTeams;
public:
//virtual string getclass() { return char2str(typeid(*(this)).name()); }
groups(int numb = 0): num_of_people(numb) {};
~groups(){};
};
//SoccerTeam group class
class SoccerTeams : public groups {
std::string teamName;
std::vector<SoccerTeams> teams;
int teamId;
public:
Players player;
void addManager();
std::string nameTeam(int);
void deletePlayer(int);
void showTeam();
void addPlayer();
void showPlayers();
void showManagers();
void exportToFile(const char *);
SoccerTeams() {};
SoccerTeams(std::string, int);
~SoccerTeams() {};
};
//FanClub group class
class FanClubs : public groups{
std::string clubName;
int clubId;
std::vector<FanClubs> fanclubs;
public:
Fans fan;
void addFans();
void showFans();
FanClubs() {};
FanClubs(std::string, int);
~FanClubs() {};
};
#endif
groups.cpp
#include <algorithm>
#include <iostream>
#include <vector>
#include <typeinfo>
#include <boost/units/detail/utility.hpp>
#include <cstdlib>
#include <fstream>
#include <list>
#include "groups.h"
using namespace std;
//Fan Club member functions
FanClubs::FanClubs(string name, int id) {
clubName = name;
clubId = id;
fanclubs.push_back(*this);
};
void FanClubs::showFans() {
cout << "Players in " << fanclubs.begin() -> clubName << endl;
fan.showFanas();
}
void FanClubs::addFans() {
int choice = 0;
cout << "1. Add a bunch of fans\n2. Add custom fans\nChoice: ";
cin >> choice;
switch(choice) {
case 1: {
int requirement;
cout << "How many fans do you need: ";
cin >> requirement;
static const string names[] = {
"Margarita", "Amalia", "Sam", "Mertie", "Jamila", "Vilma",
"Mazie", "Margart", "Lindsay", "Kerstin", "Lula", "Corinna", "Jina",
"Jimmy", "Melynda", "Demetrius", "Beverly", "Olevia", "Jessika",
"Karina", "Abdallah", "Max", "Prateek", "Aghaid"
};
for (int i = 0; i < requirement; ++i) {
fan.name = names[rand() % 24];
fan.age = (rand() % 80 + 1);
fan.sex = ((rand() % 2) ? 'M' : 'F');
fan.under_auth = false;
fan.auth_level = 0;
fans.push_back(fan);
}
break;
}
case 2: {
int requirement;
cout << "How many fans you want to add?\nnumber: ";
cin >> requirement;
for (int i = 0; i < requirement; ++i) {
cout << "======Fan " << i + 1 << "=======\n";
cout << "Enter name: ";
cin >> fan.name;
cout << "Enter age: ";
cin >> fan.age;
cout << "Enter sex: ";
cin >> fan.sex;
fan.under_auth = false;
fan.auth_level = 0;
fans.push_back(fan);
}
break;
}
default:
cout << "Incorrect choice\n";
break;
}
}
//Soccer Teams member functions
string SoccerTeams::nameTeam(int id) {
return teams.begin() -> teamName;
}
void SoccerTeams::showPlayers() {
cout << "Players in " << teams.begin() -> teamName << endl;
player.showPlayas();
}
void SoccerTeams::showManagers() {
int counter = 1;
list<ManagingDirectors>::iterator i;
for (i = directors.begin(); i != directors.end(); i++) {
cout << "Director " << counter << endl;
cout << "Works for team " << nameTeam(i -> directorId) << endl;
cout << "Name: " << i -> name << endl;
cout << "Sex: " << i -> sex << endl;
counter++;
}
}
void SoccerTeams::addPlayer() {
int newId;
int number;
cout << "Number of players to be added: ";
cin >> number;
for (int i = 0; i < number; ++i) {
cout << "\nEnter player name: ";
cin >> player.name;
cout << "Enter sex(M/F): ";
cin >> player.sex;
cout << "Enter age: ";
cin >> player.age;
cout << "Enter player id(0 for random id): ";
cin >> newId;
newId == 0 ? player.playerId = (rand() % 100 + 1) : player.playerId = newId;
player.under_auth = true;
player.auth_level = 0;
players.push_back(player);
teams.begin()->num_of_people++;
}
}
void SoccerTeams::deletePlayer(int id) {
std::vector<Players>::iterator i;
for (i = players.begin(); i != players.end(); ) {
if(i->playerId == id) {
i = players.erase(i);
teams.begin()->num_of_people--;
}
else
i++;
}
}
void SoccerTeams::showTeam() {
vector<SoccerTeams>::iterator i;
for (i = teams.begin(); i != teams.end(); ++i) {
cout << "\nTeam name: " << i -> teamName << endl;
cout << "Team id: " << i -> teamId << endl;
cout << "Number of players: " << i -> num_of_people << endl;
cout << "Average age: " << i -> player.ageCalc()/teams.begin() -> num_of_people << endl;
}
}
SoccerTeams::SoccerTeams(string tn, int id) {
teamName = tn;
teamId = id;
teams.push_back(*this);
};
void SoccerTeams::addManager() {
ManagingDirectors mandir;
int number;
cout << "How many managers you want to add: ";
cin >> number;
for (int i = 0; i < number; i++) {
cout << "Manager " << i + 1 << endl;
cout << "Enter name of the director: ";
cin >> mandir.name;
cout << "Enter the age: ";
cin >> mandir.age;
cout << "Enter the sex(M/F): ";
cin >> mandir.sex;
mandir.directorId = teams.begin() -> teamId;
mandir.auth_level = 3;
mandir.under_auth = false;
directors.push_front(mandir);
}
}
void SoccerTeams::exportToFile(const char *filename) {
ofstream outfile;
outfile.open(filename, ios::out);
vector<Players>::iterator i;
int counter = 1;
outfile << "Team Data" << endl;
outfile << "Team name : " << teamName << "\nPlayers : " << teams.begin() -> num_of_people << endl;
outfile << "Average age: " << teams.begin() -> player.ageCalc()/teams.begin() -> num_of_people << endl;
for (i = players.begin(); i != players.end(); ++i) {
outfile << "\nPlayer " << counter << endl;
outfile << "Name: " << i -> name << endl;
outfile << "Sex : " << i -> sex << endl;
outfile << "Age : " << i -> age << endl;
outfile << "Pid : " << i -> playerId << endl;
counter++;
}
outfile.close();
}
people.h
#ifndef PEOPLE_H
#define PEOPLE_H
//People base class
class people {
string name;
char sex;
int age;
bool under_auth;
int auth_level;
friend class SoccerTeams;
friend class Players;
friend class Fans;
friend class FanClubs;
public:
//virtual string getclass() { return char2str(typeid(*(this)).name()); }
people(){};
~people(){};
//virtual int get_age(){ return this->age; };
};
//players class people
class Players : public people {
int playerId;
int avgAge;
friend class SoccerTeams;
public:
void showPlayas();
float ageCalc();
Players(){};
~Players(){};
};
std::vector<Players> players;
//Class Managing Directors people
class ManagingDirectors : public people {
int directorId;
friend class SoccerTeams;
public:
ManagingDirectors(int);
ManagingDirectors() {};
~ManagingDirectors(){};
};
std::list<ManagingDirectors> directors;
//Fans people class
class Fans : public people {
public:
void showFanas();
Fans(){};
~Fans(){};
};
std::vector<Fans> fans;
#endif
people.cpp
#include <algorithm>
#include <iostream>
#include <vector>
#include <typeinfo>
#include <boost/units/detail/utility.hpp>
#include <cstdlib>
#include <fstream>
#include <list>
#include "people.h"
using namespace std;
const int vector_resizer = 50;
string char2str(const char* str) { return boost::units::detail::demangle(str); }
//Fan class member functions
void Fans::showFanas() {
int counter = 1;
vector<Fans>::iterator i;
for (i = fans.begin(); i != fans.end(); ++i) {
cout << "\nFan " << counter << endl;
cout << "Name: " << i -> name << endl;
cout << "Sex: " << i -> sex << endl;
cout << "Age: " << i -> age << endl;
counter++;
}
}
//Players class member functions
float Players::ageCalc() {
int totalAge = 0;
vector<Players>::iterator i;
for (i = players.begin(); i != players.end(); ++i) {
totalAge += i->age;
}
return totalAge;
}
void Players::showPlayas() {
int counter = 1;
vector<Players>::iterator i;
for (i = players.begin(); i != players.end(); ++i) {
cout << "\nPlayer " << counter << endl;
cout << "Name: " << i -> name << endl;
cout << "Sex: " << i -> sex << endl;
cout << "Age: " << i -> age << endl;
cout << "Player id: " << i -> playerId << endl;
counter++;
}
}
//Member functions of Managing DIrectos
ManagingDirectors::ManagingDirectors(int number) {
directorId = number;
};
In addition to these files, I also have a makefile.
//makefile
footballmaker: main.o groups.o people.o
gcc -o main main.o groups.o people.o
rm groups.o people.o
Also here's all the code in one file, the way it works right now.
I'm getting the following error when I try to make the program,
gcc -o main main.o groups.o people.o
groups.o:(.bss+0x0): multiple definition of `players'
main.o:(.bss+0x0): first defined here
groups.o:(.bss+0x20): multiple definition of `directors[abi:cxx11]'
main.o:(.bss+0x20): first defined here
groups.o:(.bss+0x40): multiple definition of `fans'
main.o:(.bss+0x40): first defined here
people.o:(.bss+0x0): multiple definition of `players'
main.o:(.bss+0x0): first defined here
people.o:(.bss+0x20): multiple definition of `directors[abi:cxx11]'
main.o:(.bss+0x20): first defined here
people.o:(.bss+0x40): multiple definition of `fans'
main.o:(.bss+0x40): first defined here
...
collect2: error: ld returned 1 exit status
makefile:3: recipe for target 'footballmaker' failed
make: *** [footballmaker] Error 1
The entire error was over 400 lines long, it is attached here.
I'm not sure how I can include files, so that I don't duplicate them, since the files are needed to make the program work, would there be a better way to split my code into files?
You define (not just declare!) variables at file scope in header file people.h. Such a variable definition will be visible to all other translation units at time of linkage. If different translation units, e.g. people.cpp and main.cpp, now include people.h, then this is as if these variable definitions had been written directly into both people.cpp and main.cpp, each time defining a separate variable with the same name at a global scope.
To overcome this, declare the variables in the header file, but define it in only one translation unit, e.g. people.cpp. Just declaring a variable means putting keyword extern in front of it (telling the compiler that variable definition will be provided by a different translation unit at the time of linking):
// people.h
extern std::vector<Players> players;
extern std::list<ManagingDirectors> directors;
extern std::vector<Fans> fans;
// people.cpp
std::vector<Players> players;
std::list<ManagingDirectors> directors;
std::vector<Fans> fans;
I am asked to do this code and i need to use array or something similar to print out different classes. The only way i know is individually doing every single class is there a faster way of doing this. Following is the way i am using at the moment.
Ground_Transport Gobj;
Air_Transport Aobj;
Sea_Transport Sobj;
Car Cobj;
Train Tobj;
Bus Bobj;
Gobj.estimate_time();
Gobj.estimate_cost();
cout << Gobj.getName() << endl;
Bobj.estimate_time();
Bobj.estimate_cost();
cout << Bobj.getName() << endl;
Sobj.estimate_time();
Sobj.estimate_cost();
cout<<Sobj.getName()<<endl;
Aobj.estimate_time();
Aobj.estimate_cost();
cout << Aobj.getName() << endl;
Cobj.estimate_time();
Cobj.estimate_cost();
cout << Cobj.getName() << endl;
Tobj.estimate_time();
Tobj.estimate_cost();
cout << Tobj.getName() << endl;
Transport_KL_Penang Kobj;
cout << Kobj.getName() << endl;
This is the header file Transport_KL_Penang
#include <iostream>
#include <string>
using namespace std;
class Transport_KL_Penang
{
public:
Transport_KL_Penang() {}
virtual string getName() {
return Name;
}
int Time_in_hours1 ;
int Time_in_hours2 ;
int Cost_in_RM1 ;
int Cost_in_RM2 ;
void estimate_time() ;
void estimate_cost() ;
private:
static string Name;
};
void Transport_KL_Penang::estimate_time()
{
cout << "It takes " << Time_in_hours1 << "-" << Time_in_hours2 <<
" hours if you use " << Name << endl;
}
void Transport_KL_Penang::estimate_cost()
{
cout << "It will cost around " << Cost_in_RM1 << "-" << Cost_in_RM2 <<
"RM if you use " << Name << endl;
}
If you don't need a specific object name, you can write something as a code below, creating a multiples generics objects:
#include <iostream>
#include <cstdlib>
#include <time.h>
class Myclass {
private:
int randTime;
float cost;
public:
void estimate_time(){
randTime = rand()%100;
}
void estimate_cost(){
cost = randTime * 0.2;
}
float getEstimateCost(){
return cost;
}
};
int main(){
srand(time(NULL));
int numberOfObjects = 7;
Myclass obj[numberOfObjects];
//input
for(int i = 0; i < numberOfObjects; i++){
obj[i].estimate_time();
obj[i].estimate_cost();
}
// printing
for(int i = 0; i < numberOfObjects; i++){
std::cout << obj[i].getEstimateCost() << std::endl;
}
return 0;
}
I have a program for my class to read in information from a file, as an array, using a function and I've coded this the same way I did for classes last year and I'm not sure why it's not working. I'm supposed to also add more to this but wanted to try to figure out why it's not working with what it already has.
I don't think it's reading the file in because nothing comes out on the output file or the window that pops up when it runs.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
const int maxs = 50;
struct stype
{
int crn;
string name;
int crhrs;
int numstu;
int stucrhrs;
string prof;
};
stype initrec = { 0.0, "course", 0.0, 0.0, 0.0, "prof" };
void initem(stype p[], int &numc)
{
int i;
for (i = 0; i < maxs; i++) p[i] = initrec;
numc = 0;
}
void readem(stype p[], int &numc)
{
int i = 0;
ifstream fin;
fin.open("program1.dat");
while (!fin.eof())
{
fin >> p[i].crn >> p[i].name >> p[i].crhrs >> p[i].numstu >> p[i].stucrhrs >> p[i].prof;
i++;
}
numc = i;
cout << "readem reached " << endl;
}
void printem(stype p[], int &numc, ofstream &fout)
{
int i;
for (i = 0; i < numc; i++)
{
fout << left << setw(10) << p[i].crn << left << setw(15) << p[i].name << left
<< setw(15) << p[i].numstu << right << setw(2) << p[i].crhrs << right <<
setw(2) << p[i].stucrhrs << right << setw(10) << p[i].prof << endl;
}
cout << "printem reached " << endl;
}
void swapem(stype &a, stype &b)
{
stype temp;
temp = a;
a = b;
b = temp;
cout << "swapem reached " << endl;
}
void sortem()
{
cout << "sortem reached " << endl;
}
void getaverage()
{
cout << "getaverage reached " << endl;
}
void credithours()
{
cout << "Credit hours totalled. " << endl;
}
void main()
{
int crn[maxs], crhrs[maxs], stucrhrs[maxs];
string name[maxs], prof[maxs];
stype p[maxs];
int numc;
ofstream fout;
fout.open("program1.out");
fout.setf(ios::fixed);
fout.precision(2);
initem(p, numc);
readem(p, numc);
printem(p, numc, fout);
getaverage();
sortem();
printem(p, numc, fout);
system("pause");
}
I'm trying to read names and ages from user, until user inputs "stop". Then just print all these values. Please help me , I'm just the beginner in C++
// Pass.cpp
// Reading names and ages from user and outputting them
#include <iostream>
#include <iomanip>
#include <cstring>
using std::cout;
using std::cin;
using std::endl;
using std::setw;
using std::strcmp;
char** larger(char** arr);
int* larger(int* arr);
void read_data(char*** names, int** ages);
void print_data(char*** names, int** ages);
int main()
{
char** names = new char*[5];
char*** p_names = &names;
int* ages = new int[5];
int** p_ages = &ages;
read_data(p_names,p_ages);
print_data(p_names,p_ages);
}
void read_data(char*** names, int** ages)
{
const char* sent = "stop";
const int MAX = 15;
int count = 0;
char UI[MAX];
cout << "Enter names and ages."
<< endl << "Maximum length of name is " << MAX
<< endl << "When stop enter \"" << sent << "\".";
while (true)
{
cout << endl << "Name: ";
cin.getline(UI,MAX,'\n');
if (!strcmp(UI, sent))
break;
if (count + 1 > sizeof (&ages) / sizeof (&ages[0]))
{
*names = larger(*names);
*ages = larger(*ages);
}
*names[count] = UI;
cout << endl << "Age: ";
cin >> *ages[count++];
}
}
void print_data(char*** names, int** ages)
{
for (int i = 0; i < sizeof(*ages) / sizeof(*ages[0]);i++)
{
cout << endl << setw(10) << "Name: " << *names[i]
<< setw(10) << "Age: " << *ages[i];
}
}
char** larger(char** names)
{
const int size = sizeof(names) / sizeof(*names);
char** new_arr = new char*[2*size];
for (int i = 0; i < size; i++)
new_arr[i] = names[i];
return new_arr;
}
int* larger(int* ages)
{
const int size = sizeof(ages) / sizeof(*ages);
int* new_arr = new int[2 * size];
for (int i = 0; i < size; i++)
new_arr[i] = ages[i];
return new_arr;
}
You are really over complicating things.
Given the original problem:
Write a program that reads a number (an integer) and a name (less than
15 characters) from the keyboard. Design the program so that the data
is done in one function, and the output in another. Store the data in
the main() function. The program should end when zero is entered for
the number. Think about how you are going to pass the data between
functions
The problem wants you to think about passing parameters to functions. A simple solution would be:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;
// Pass in a char array and an integer reference.
// These values will be modified in the function
void read_data(char name[], int& age)
{
cout << endl << "Age: ";
cin >> age;
cin.ignore();
cout << endl << "Name: ";
cin.getline(name, 16);
}
// Pass a const array and an int value
// These values will not be modified
void print_data(char const *name, int age)
{
cout << endl << setw(10) << "Name: " << name
<< setw(10) << "Age: " << age;
}
int main()
{
char name[16];
int age;
cout << "Enter names and ages."
<< endl << "Enter 0 age to quit.";
do {
read_data(name, age);
print_data(name, age);
} while (0 != age)
}
EDIT: Modified per user3290289's comment
EDIT2: Storing data in an array
// Simplify by storing data in a struct (so we don't have to manage 2 arrays)
struct Person {
char name[16];
int age;
};
// Returns how many People were input
int read_data(Person*& arr)
{
int block = 10; // How many persons to allocate at a time
arr = NULL;
int arr_size = 0;
int index = 0;
while (true) {
if (index == arr_size) {
arr_size += block;
arr = (Person *)realloc(arr, arr_size * sizeof(Person)); // Reallocation
// Should check for error here!
}
cout << endl << "Age: ";
cin >> arr[index].age;
cin.ignore();
if (0 == arr[index].age) {
return index;
}
cout << endl << "Name: ";
cin.getline(arr[index++].name, 16);
}
}
void print_data(Person *arr, int count)
{
for (int i = 0; i < count; i++) {
cout << endl << setw(10) << "Name: " << arr[i].name
<< setw(10) << "Age: " << arr[i].age;
}
}
int main()
{
Person *arr;
int count = read_data(arr);
print_data(arr, count);
free(arr); // Free the memory
}
try this:
#include <iostream>
#include <iomanip>
#include <vector>
#include <sstream>
using std::cout;
using std::cin;
using std::endl;
using std::setw;
using std::strcmp;
void read_data(std::vector<std::string> &names, std::vector<int> &ages);
void print_data(std::vector<std::string> &names, std::vector<int> &ages);
int main()
{
std::vector<std::string> names;
std::vector<int> ages;
read_data(names, ages);
print_data(names, ages);
}
void read_data(std::vector<std::string> &names, std::vector<int> &ages)
{
const char* sent = "stop";
cout << "Enter names and ages."
<< endl << "When stop enter \"" << sent << "\".";
while (true)
{
std::string input;
cout << endl << "Name: ";
std::getline(cin, input);
if (!strcmp(input.c_str(), sent))
break;
names.push_back(input);
cout << endl << "Age: ";
std::string age;
std::getline(cin, age);
ages.push_back(atoi(age.c_str()));
}
}
void print_data(std::vector<std::string> &names, std::vector<int> &ages)
{
for (int i = 0; i < names.capacity() ; i++)
{
cout << endl << setw(10) << "Name: " << names.at(i)
<< setw(10) << "Age: " << ages.at(i);
}
}
One problem I see is this if statement:
if (count + 1 > sizeof (&ages) / sizeof (&ages[0]))
&ages is the address of an int**, a pointer, and so it's size is 8 (usually) as that is the size of a pointer type. The function does not know the size of the array, sizeof will only return the correct answer when ages is declared in the same scope.
sizeof(&ages) / sizeof(&ages[0])
will always return 1
I believe one natural solution about this problem is as follows:
create a "std::map" instance. Here std::map would sort the elements according to the age. Here my assumption is after storing the data into the container, you would like to find about a particular student age/smallest/largest and all various manipulation with data.Just storing and printing the data does not make much sense in general.
create a "std::pair" and take the both input from the user into the std::pair "first" and "second" member respectively. Now you can insert this "std::pair" instance value into the above "std::map" object.
While printing, you can now fetch the each element of "std::map" in the form of "std::pair" and then you can display pair "first" and "second" part respectively.