I'm struggling with an error that I haven't been able to find the solution for. I can't seem to understand why "Location" is not found as a class. here is me header file:
#ifndef CLASS2_HPP
#define CLASS2_HPP
class Passenger
{
public:
enum class Location
{
Business,
Economy,
Vip
};
Passenger(Location clas_s, char* firstName, char* secondName, int seat, int terminal, float time_of_departure);
const char* get_location() const;
int get_seat() const;
int get_terminal() const;
float get_time() const;
char* get_firstName() const;
char* get_secondName() const;
void print() const;
private:
Location _clas_s;
char _firstName;
char _secondName;
int _seat;
int _terminal;
float _time_of_departure;
};
#endif // CLASS2
And here is my cpp file:
#include <iostream>
#include "Class2.hpp"
using namespace std;
Passenger::Passenger(Location clas_s, char* firstName, char* secondName, int seat, int terminal, float time_of_departure)
: _clas_s(clas_s), _firstName(firstName), _secondName(secondName), _seat(seat), _terminal(terminal), _time_of_departure(time_of_departure) {};
void Passenger::print() const
{
cout << "Your name is " << _firstName
<< " " << _secondName << endl
<< "Your class is " << get_location() << endl
<< "Your seat is " << _seat << endl
<< "Your terminal is " << _terminal << endl
<< "Your time of departure is " << _time_of_departure << endl;
}
const char* Passenger::get_location() const
{
switch (_clas_s)
{
case Location::Business : return "Business";
case Location::Economy : return "Economy";
case Location::Vip : return "Vip";
}
}
int main() {
Passenger p((Passenger::Location::Vip), 'John', 'Johnson', 25, 2, 13.53);
p.print();
return 0;
}
Thanks in advance.
It seems you are on C++03, so make
enum Location
{
Business,
Economy,
Vip
};
And
case Business : return "Business";
case Economy : return "Economy";
case Vip : return "Vip";
Edit: I was wrong about
You forgot to set Passenger::Passenger(Passenger:: Location
clas_s,...
When you create your Passenger you have to pass strings using the double quotes, not single quotes (which are for single characters only):
Passenger p((Passenger::Location::Vip), "John", "Johnson", 25, 2, 13.53);
Then, you have declared _firstName and _secondName as char. But this would only let you store a single character! A simple solution is to use an array (but it would be much better to use the appropriate structure, which is a std::string, so that you don't need to worry about the size):
char _firstName[50];
char _secondName[50];
Then, to initialize them you need to #include <cstring> and, in the constrcutor's body (not in the initializer list!)
strcpy(_firstName, firstName);
strcpy(_secondName, secondName);
(Again, a std::string would be better, you could set it in the initializer list)
With these changes it compiles and the output, as expected, is:
Your name is John Johnson
Your class is Vip
Your seat is 25
Your terminal is 2
Your time of departure is 13.53
Tested on ideone.
Are you getting this error:
Class.cpp:24:14: warning: use of enumeration in a nested name specifier is a C++11 extension [-Wc++11-extensions]
case Location::Business : return "Business";
As it states, its a C++11 feature, so try compiling your code with "-std=c++11" option. Or change the switch case with integer values:
switch (_clas_s)
{
case 0: return "Business";
case 1: return "Economy";
case 2: return "Vip";
}
Hope that helps.
Related
The task is to:
Create the abstract class Train nd two derived Passenger/Freight.
Create a container. Type of container dynamic array (the size of the array is defined as arguments of the constructor).
Save the results to the file and delete them from it.
Search in the container and print the train by his number.
I have some questions about where is better to create userInput, storeToArray functions. In the menu file or class as a virtual function or create one more h/cpp?
Why does is the error C2228(VS19) in Menu.cpp/void storeToArray()?
#include"Train.h"
void storeToArray()
{
Train* t;
t = new Train();
t.userInput;
//collection.push_back(t);
}
1>Menu.cpp
1>C:\Users\Admin\source\repos\Menu.cpp(29,3): warning C4002: too many arguments for function-like macro invocation 'assert'
1>C:\Users\Admin\source\repos\Menu.cpp(88,1): warning C4002: too many arguments for function-like macro invocation 'assert'
1>C:\Users\Admin\source\repos\Menu.cpp(105,5): error C2039: 'userInput': is not a member of 'Train'
1>C:\Users\Admin\source\repos\train.h(7): message : see declaration of 'Train'
Does my way of solving this problem is optimal?
How can I make the program better?
https://github.com/brenqP/Course
Menu.h:
#pragma once
#include "PassengerTrain.h"
#include "FreightTrain.h"
#include "train.h"
void greeting();
void showMenu();
void userMenu();
void userInput();
void storeToArray();
//void printInput();
menu.cpp
#include "Menu.h"
#include "file.h"
#include <iostream>
#include <cassert>
void greeting() { std::cout << "Welcome to the Train simulator!\n\n"; }
void showMenu()
{
std::cout<<
"1)Create new train route for the passenger train.\n"<<
"2)Create new train route for the freight train.\n"<<
"3)Save results to the file.\n" <<
"4)Open results from the file.\n" <<
"5)Find train by number.\n"<<
"6)Exit.\n\n";
}
void userMenu()
{
showMenu();
std::cout << "Choose one of the options by printing the number.\n";
int option = 0;
std::cin >> option;
std::cout << "You have chosen the " << option << " option\n";
assert("Invalid input.Please try again later.",option > 0 && option < 7);
//system("cls");
switch (option)
{
case 1:
{//Train:: ;
userInput();
userMenu();
break;
}
case 2:
{
userInput();
userMenu();
break;
}
case 3:
storeToFile();
userMenu();
break;
case 4:
executeFile();
userMenu();
break;
case 5:std::cout << "later";
userMenu();
break;
case 6:
{
std::cout << "\nOkay, see you next time.\n";
std::exit(0);
break;
}
default:
std::cout << "Something went wrong, please try again later\n";
std::exit (0);
}
}
void userInput()
{
std::cout << "Input the number of the train you`re willing to create\n";
int number = 0;
std::cin >> number;
assert(number > 0);
std::cout << "Input the path of the train you`re willing to create\n"
<< "Ex. London-Paris\n";
std::string path{ "N / A - N / A" };
std::cin >> path;
std::cout << "Input the time of the departure\n"
<< "Ex. 23.22\n";
double time_of_departure{ 0 };
std::cin >> time_of_departure;
assert(time_of_departure >= 0 && time_of_departure < 24.0,
"Invalid time of the departure ");
//system("cls");
Train g{ number,path,time_of_departure };
g.print();
}
error
void storeToArray()
{
Train* t;
t = new Train();
t.userInput;
//collection.push_back(t);
}
Train.cpp
#include "train.h"
Train::Train(int number, std::string path, double time_of_departure):
m_number{ number },
m_path{ path },
m_time_of_departure{ time_of_departure }
{
}
Train::~Train()
{
}
//void Train::setPassengerTrain()
//{
//Train:setNumber();
//
//}
void Train::setNumber(int number)
{
m_number = number;
}
void Train::setPath(int path)
{
m_path = path;
}
void Train::setTime_of_departure(int time_of_departure)
{
m_time_of_departure = time_of_departure;
}
void Train::print()
{
std::cout<< "The train number \t" <<
getNumber() << " \t "<<
getPath() << " \tis departed at\t " <<
//bug if there is a /t; print 121314 instead of 1
getTime_of_departure()<<'\n' << std::endl;
}
train.h
#pragma once
#include <string>
#include<iostream>
#include <cassert>
#include <vector>
class Train
{
protected:
int m_number{0};
std::string m_path{"N/A-N/A"};
double m_time_of_departure{0};
public :
//some constructors
Train() = default;
Train(int number, std::string path, double time_of_departure);
//destructor
virtual ~Train();
//void setPassengerTrain();
virtual int getNumber() { return m_number; }
void setNumber(int number);
virtual std::string getPath() { return m_path; }
void setPath(int path);
virtual double getTime_of_departure(){ return m_time_of_departure; }
void setTime_of_departure(int time_of_departure);
void print();
};
PassengerTrain.h
#pragma once
#include "train.h"
class PassengerTrain :public Train
{
int m_number{ 0 };
std::string m_path{ "N/A-N/A" };
double m_time_of_departure{ 0 };
public:
//some constructors
PassengerTrain() = default;
PassengerTrain(int number, std::string path, double time_of_departure);
//destructor
~PassengerTrain();
//void setPassengerTrain();
int getNumber() { return m_number; }
void setNumber(int number);
std::string getPath() { return m_path; }
void setPath(int path);
double getTime_of_departure() { return m_time_of_departure; }
void setTime_of_departure(int time_of_departure);
void print();
};
PassengerTrain.cpp
#include"PassengerTrain.h"
PassengerTrain::PassengerTrain(int number, std::string path, double time_of_departure):
m_number{ number },
m_path{ path },
m_time_of_departure{ time_of_departure }{}
PassengerTrain::~PassengerTrain()
{
}
void PassengerTrain::print()
{
std::cout << "The passenger train number \t" <<
getNumber() << " \t " <<
getPath() << " \tis departed at\t " <<
//bug if there is a /t; print 121314 instead of 1
getTime_of_departure() << '\n' << std::endl;
}
The freightTrain is the same as passengerTrain.
This is maybe not a complete answer (since you did not provide a minimally reproducible example to actually work on) but there are many obvious things to fix. Before even looking at details:
C++ is case sensitive, Train and train are two different things to C++, this also applies to include files Train.h and train.h. You CANNOT mix those: fix.
C++ is very flexible in terms of your text formatting, but in some places white-spaces are mandatory. In particular #include"Train.h" must be #include "Train.h"
Let's look at:
#include"Train.h" // at white space --> #include "Train.h"
void storeToArray()
{
Train* t;
t = new Train();
t.userInput;
//collection.push_back(t);
}
where userInput is not a method or property of Train but a free function defined in Menu.h. Thus, very good practice is to also include #include "Menu.h" (this won't fix any of your problems yet).
Another issue is of course that t is a pointer, not an object. You cannot use the dot operator t., but you have to use the arrow operate t->. But this also does not solve any of your problems yet.
It seems to me what you want to achieve is to ask the user for input, create a new Train object, and store it in a collection. For this you better start by changing the definition of void userInput(); in Menu.h to Train* userInput();
Then in "menu.cpp" you also change it to Train* userInput() { and furthermore you change the last to lines of the userInput function from
Train g{ number,path,time_of_departure };
g.print();
(which actually does accomplish nothing useful) to
Train* train = new Train(number, path, time_of_departure);
train->print();
return train; // <-- this is really important since it return your train to the caller
If you do those changes, you at least can produce trains, and store them in a collection as you wish.
im trying to create a object called player in class player.
#include <string>
#ifndef PLAYER_HH
#define PLAYER_HH
using namespace std;
class Player
{
public:
Player(string name, int points);
const string get_name();
int get_points();
void add_points(int pts);
bool has_won();
private:
string _name;
};
#endif // PLAYER_HH
from player.cpp:
#include <string>
using namespace std;
Player::Player(string name):
_name(name), _points(0){
}
Now, the problem is, in the main function i get this error:
error: no matching function for call to ‘Player::Player(const char [6])’
Player player1 = Player("Matti");
^
Shouldn't the compiler be able to convert it to a string?
edit: Here is the full main.cpp that i'm not supposed to be changing:
#include <cstdlib>
#include <iostream>
#include <string>
#include "player.hh"
int main()
{
Player player1 = Player("Matti");
Player player2 = Player("Teppo");
Player* in_turn = 0;
int turn = 1;
while (true)
{
if (turn % 2 != 0)
{
in_turn = &player1;
}
else
{
in_turn = &player2;
}
std::cout << "Enter the score of player " << in_turn->get_name()
<< " of turn " << turn << ": ";
int pts = 0;
std::cin >> pts;
in_turn->add_points(pts);
if (in_turn->has_won())
{
std::cout << "Game over! The winner is " << in_turn->get_name() << "!" << std::endl;
return EXIT_SUCCESS;
}
std::cout << std::endl;
std::cout << "Scoreboard after turn " << turn << ":" << std::endl;
std::cout << player1.get_name() << ": " << player1.get_points() << "p" << std::endl;
std::cout << player2.get_name() << ": " << player2.get_points() << "p" << std::endl;
std::cout << std::endl;
turn += 1;
}
return EXIT_SUCCESS;
}
You guys are awesome with your fast answers :-)
You declared the constructor of player as Player(string name, int points);.
If you define a function with two parameters you have to use both.
Create your object with
Player player1 = Player("Matti", 0);
If you still want to call it with just one parameter you have to set a default value like this.
class Player
{
public:
...
Player(string name, int points = 0); // replace 0 with whatever you want to be default.
...
}
Then you can use both variants. The one above and the one you attempted
Player player1 = Player("Matti");
Of course the function header of your definition has to match the one in the declaration:
Player::Player(string name, int points):
_name(name), _points(points){
}
It's important not to write the default value inside dhe definition because this will most likely produce an compiler error.
The conversion from const char[6] to std::string will work and is not the issue here.
Your constructor has two parameters, you cannot simply omit the second one. If you like to create Player objects with a default score, declare your constructor as:
Player(string name, int points = 0);
First of all, you declare your constructor having two parameters:
Player(string name, int points);
but define it as having only one:
Player::Player(string name):
_name(name), _points(0){
}
That should give you compilation error. Either remove the second param from the declaration in class body and keep main.cpp as it is or add second param to the definition in player.cpp:
Player::Player(string name, int points):
_name(name), _points(points){
}
and then specify value for 'points' explicitly:
Player("Matti", 0);
You can also have both - just add default value for points:
class Player
{
...
Player(string name, int points = 0);
};
Then, both of these lines will work:
Player player1 ("Matti");
Player player2 ("Matti", 0);
writing this program for my c++ class and im running into an issue. My program reads the inputtted name and stores it into name it then wants to check for correct parameters under _name.. here are my class and its header file.
My error is specifically under ::setName where i want to check or set my inputted name with _name for correct output under ::display()
PhoneNumber.cpp
using namespace oop244;
void PhoneNumber::display() const{
cout << "name: " << _name << ", Phone number: (" << _areacode << ") " << _localNumber / 10000 << "-" << _localNumber % 10000 << endl;
}
bool PhoneNumber::isValid() const
{
if (correctNum == false && correctArea == false){
cout << _name << " does not have a valid phone number." << endl;
return false;
}
else{
return true;
}
}
void PhoneNumber::setName(const char name[])
{
cout << name << endl;
_name = name;
}
PhoneNumber.h
#define MAX_NAME_LENGTH 40
#define PHNO_MAX 999999
#define PHNO_MIN 100000
#define AREACODE_MIN 100
#define AREACODE_MAX 999
namespace oop244{
class PhoneNumber{
private:
char _name[MAX_NAME_LENGTH + 1];
int _areacode;
int _localNumber;
bool _validPhoneNumber;
public:
void setName(const char name[]);
void setPhoneNumber(int areaCode, int number);
void display() const;
bool isValid() const;
};
};
use standard string
#include <string>
and use
std::string _name;
in your class declarations instead of
char _name[MAX_NAME_LENGTH + 1];
alternatively use c-style str-functions, as suggested in another answer
You can't assign raw arrays. You need to copy the contents.
Assuming your class teacher forces you to use char arrays, you can for example use strncpy to copy the characters:
strncpy(_name, name, MAX_NAME_LENGTH);
You need to #include <cstring> for this.
If your class teacher allows it, better use std::array<char,MAX_NAME_LENGTH> or even std::string. Both can be copied by assigning.
Okay, so this is effectively the first C++ I have ever written. Consequently, my attempts to research this Segmentation Fault error have failed to yield a useful response that I can understand. Most suggestions say that I'm exceeding the heap memory, but I don't see how I could be in this code. Maybe I'm trying to reference something that I can't reference?
Can someone please take a look at this code and possibly tell me what is causing this error? The code compiles fine, it just throws this error when it runs. I have tried commenting out all the code involving vectors, and that didn't solve the problem. I'm guessing it's something stupid that I'm missing or just a concept about C++ that I don't understand. Either way, some insight would be much appreciated! Thanks in advance.
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
const int DEFAULT_SIZE = 15;
//---------------------------------User----------------------------------------------------------------------------------
//User Interface Definition
class User
{
public:
User(string nameValue);
string getName();
string getWall();
string getHome();
private:
string name;
};
//User Implementation Definition
User::User(string nameValue) : name(nameValue)
{
}
string User::getName()
{
return name;
}
//---------------------------------Group----------------------------------------------------------------------------------
//Group Interface Definition
class Group
{
public:
Group(string nameValue);
string getName();
void addMember(User newMember);
private:
string name;
vector<User> members;
};
//Group Implementation
Group::Group(string nameValue) : name(nameValue)
{
}
string Group::getName()
{
return name;
}
void Group::addMember(User newMember)
{
members.push_back(newMember);
}
//---------------------------------MessageBuffer----------------------------------------------------------------------------------
//MessgeBuffer Interface Declaration
class MessageBuffer
{
public:
MessageBuffer();
void insert(string user, string recipient, string message);
string readByGroup(string groupName);
string readByUser(string userName);
string readPublic();
private:
string buffer;
};
//MessageBuffer Implementation
MessageBuffer::MessageBuffer() : buffer("")
{
}
void MessageBuffer::insert(string user, string recipient, string message)
{
buffer = "|<" + user + "::" + recipient + ">|" + message + buffer;
}
string MessageBuffer::readByGroup(string groupName)
{
return "Something";
}
string MessageBuffer::readByUser(string userName)
{
return "Something";
}
string MessageBuffer::readPublic()
{
return "Something";
}
//---------------------------------System-------------------------------------------------------------------------------
//System Interface Definition
class System
{
public:
System();
void start();
private:
bool running;
User currentUser;
MessageBuffer messageBuffer;
vector<User> users;
vector<Group> groups;
};
//System Implementation Definition
System::System() : running(false), currentUser(0)
{
}
void System::start()
{
running = true;
string userSelection;
cout << "===========================================================" << endl;
cout << "|\t Welcome to the Auburn Messaging System! \t |" << endl;
cout << "===========================================================" << endl;
while (running) {
cout << "1) Create a new user\n";
cout << "2) Broadcast a message\n";
cout << "3) Multicast a message\n";
cout << "4) Unicast a message\n";
cout << "5) Display Wall page\n";
cout << "6) Display Home page\n";
cout << "7) Create a new group\n";
cout << "8) Join a group\n";
cout << "9) Switch to a different user\n";
cout << "10) Quit Auburn Messaging System\n";
cin >> userSelection;
if (userSelection == "1")
{
running = false;
}
}
}
//----------------------------------------------------------------------------------------------------------------------
int main() {
cout << "Part 1";
System system1;
cout << "Part 2";
system1.start();
cout << "Part 3";
return 0;
}
In the System constructor, currentUser(0) is attempting to initialise a the first parameter of the User constructor (a string) with a literal zero which will be interpreted as a null char pointer.
The std::string constructor (look for basic_string<char> in the debugger) which constructs a string from a char* will be called with a null pointer, which it will dereference and invoke undefined behaviour.
I'm trying to add some songs to a vector inside a class. One of the values I'm storing is an int representing the song. It's essentially a counter. The first song I add should have the value 1, the second value two and so forth. But It's getting other strange values like big random numbers (positives and negatives). I can't wrap my head around what I'm doing wrong. This is the code:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Jukebox{
public:
void addSong(string artist, string title, string filename) {
song s {++songCounter, artist, title, filename};
Songs.push_back(s);
}
void printSong (int song) {
cout << Songs[song].no << ". ";
cout << Songs[song].artist << " - ";
cout << Songs[song].title << " : ";
cout << Songs[song].filename << endl;
}
private:
struct song {
int no;
string artist;
string title;
string filename;
};
vector<song> Songs;
int songCounter;
};
int main() {
Jukebox jbox;
jbox.addSong("U2", "Magnificent", "U2-Magnificent.mp3");
jbox.addSong("Sting", "Englishman in New York", "Sting-Englishman_in_New_York.mp3");
jbox.addSong("U2", "One", "U2-One.mp3");
jbox.printSong(0);
jbox.printSong(1);
jbox.printSong(2);
return 0;
}
Update
Ok, I'm probably stupid and should read more about classes before trying to implement this. But I think I did read and I still don't get it. This is what my class looks like now (which won't work):
class Jukebox(): songCounter(0)
{
public:
void addSong(string artist, string title, string filename) {
songCounter++;
song s {songCounter, artist, title, filename};
Songs.push_back(s);
}
void printSong (int song) {
cout << Songs[song].no << ". ";
cout << Songs[song].artist << " - ";
cout << Songs[song].title << " : ";
cout << Songs[song].filename << endl;
}
private:
int songCounter;
struct song {
int no;
string artist;
string title;
string filename;
};
vector<song> Songs;
};
Final word
Ok. From the example I've seen of c++ contructor classes I had some kind of wrong impression of how they worked. Now I think I'm getting it a little bit more. But the syntax still seems strange to me. But I try to read more so I really understand it. Here is what I did and to seems to work:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Jukebox {
public:
void addSong(string artist, string title, string filename) {
songCounter++;
song s {songCounter, artist, title, filename};
Songs.push_back(s);
}
void printSong (int song) {
cout << Songs[song].no << ". ";
cout << Songs[song].artist << " - ";
cout << Songs[song].title << " : ";
cout << Songs[song].filename << endl;
}
Jukebox(): songCounter(0) {} // Constructor
private:
int songCounter;
struct song {
int no;
string artist;
string title;
string filename;
};
vector<song> Songs;
};
int main() {
Jukebox jbox;
jbox.addSong("U2", "Magnificent", "U2-Magnificent.mp3");
jbox.addSong("Sting", "Englishman in New York", "Sting-Englishman_in_New_York.mp3");
jbox.addSong("U2", "One", "U2-One.mp3");
jbox.printSong(0);
jbox.printSong(1);
jbox.printSong(2);
return 0;
}
You did not initialize songCounter in your constructor.
Jukebox(): songCounter(0),//....other members
If you do not initialize it, then it may have any random value and that leaves your program in an Undefined State.
Always be careful while using unitialized variables, it often leads to Undefined Behavior and your program is a good example of it.
Also, I am not sure of your design but probably it should be a static member if you want to use it as a counter, which maintains state for all objects of your Song class.
Or
You will have to explicitly set it to a proper value at time of creating a Song object.
Okay its a counter for JukeBox and not Song class so its still okay to be a member.
You didn't initialize the variable songCounter.
Add the following to the class definition of Jukebox:
Jukebox(): songCounter(0) {}
you need a constructor for Jukebox and in that you need to initialise the counter to 0.
I think you should initialize songCounter to be 0. In the public part of the class:
public Jukebox() : songCounter(0) {}
Where do you initialise songCounter? In C++, primitives aren't zero initialised by default. You need to add
: songCounter(0)
to your constructor.