I'm very new to the program world and I am stuck at the moment. I'm suppose to design a bookrecord that contains the title, author, publisher, category (Dewey decimal), and date of publication. For booklist I need to know how to add a new bookrecord object, find a bookrecord given the title, remove a bookrecord object, and show all the bookrecord objects. For booklistUI, I need the menu, command processor, add records, remove records, display all records. I am sort of lost as to where I should begin how would I start it out? I do have some of it so far... is it correct?
This is what I have so far
/*
Title: CSU Bodie.cpp
Description: implements three classes to make a simple searchable list of the library holdings.
*/
#include <iostream>;
#include <string>;
#include <vector>;
using namespace std;
//Define a name class...
class ShortName {
string FirstName;
string LastName;
public:
ShortName(); //Define a default constructor...
ShortName(string, string); //...and an initializing one...
//Define some mutators...
void SetFirst(string First) { FirstName = First; }
void SetLast(string Last) { LastName = Last; }
//...and some accessors...
string GetFirst() { return FirstName; }
string GetLast() { return LastName; }
};
ShortName::ShortName()
{
FirstName = "";
LastName = "";
}
ShortName::ShortName(string First, string Last)
{
FirstName = First;
LastName = Last;
}
//Define a list class...
class ShortNameList {
vector<ShortName> List; //Create a specific sized list...
public:
ShortNameList() {;} //Nothing for it to do at this point...
void AddRecord(string, string);
void ShowList();
};
void ShortNameList::AddRecord( string First, string Last)
{
ShortName NameBuffer;
NameBuffer.SetFirst(First);
NameBuffer.SetLast(Last);
List.push_back(NameBuffer);
}
void ShortNameList::ShowList()
{
int K;
for(K = 0 ; K < List.size() ; K++)
cout << List[K].GetFirst() << " " List[K].GetLast() << endl;
}
class ShortNameUI {
ShortNameList Collection;
public:
ShortNameUI() {;}
void Menu();
void AddNewRecord();
void RunIT();
};
//This gives us options...
void ShortNameUI::Menu()
{
cout << "Choices..." << endl;
cout << "====================================================================" << endl;
cout << "\\tAdd.........allows the user to enter names." << endl;
cout << "\\tDisplay......shows the names." << endl;
cout << "\\tQuit.........terminates the program" << endl;
cout << "====================================================================" << endl;
}
void ShortNameUI::RunIT()
{
string Command;
while(true) {
Menu();
cout << "Command: ";
getline(cin, Command);
if(Command == "Quit")
break;
else if(Command == "Add")
AddNewRecord();
else if(Command == "Display")
Collection.ShowList();
}
}
void ShortNameUI::AddNewRecord()
{
string First, Last;
cout << "Enter Names Below, Stop To Quit" << endl;
while(true) {
cout << "First Name: ";
getline(cin, First);
if(First == "Stop")
break;
cout << "Last Name: ";
getline(cin, Last);
if(Last == "Stop")
break;
Collection.AddRecord(First, Last);
}
}
int main()
{
ShortNameUI NameList;
NameList.RunIT();
}
}
Yes, what you have is a good start - once you fix compilation.
Preprocessor directives are not statements so should not be terminated with ;
There is a stray } at the end of the file.
You seem get that adding the full book details will be much the same. The key thing is that you need to find a book from the title. The simplest thing to do is to change from a vector<> to store the books to a map<>.
typedef std::string Title;
class BookDetails
{
// etc.
};
typedef std::map<Title, BookDetails> BookCollection;
Look up the documentation on std::map<> to see how it used.
Please try to pass parameters as a reference instead of passing by values. For eg.
instead of
void SetFirst(string First);
try to use
void SetFirst(string& First);
better still, if you are sure that the value is not going to change inside the function use like this SetFirst(const string& First);
This will save you from grief later.
Is this a console application or windows application that you are developing? If Console application the UI will be straight forward, but if Windows application you have to use either MFC or pure Win32.
Related
I am trying to develop a text adventure in C++ where users can input string commands (ex. "take apple").
Here is a very naive sample of code I came up with:
# include <iostream>
using namespace std;
class fruit{
public:
string actual_name;
fruit(string name){
actual_name = name;
}
take() {
cout << "You take a " << actual_name << "." << endl;
}
};
fruit returnObjectFromName(string name, fruit Fruits[]){
for(int i = 0; i <= 1; i++){ // to be modified in future depending on Fruits[] in main()
if (Fruits[i].actual_name == name)
return Fruits[i];
}
}
int main(){
string verb;
cout << "Enter verb: ";
cin >> verb;
string object;
cout << "Enter object: ";
cin >> object;
fruit apple("apple");
fruit Fruits[] = { apple }; // to be extended in future
// returnObjectFromName(object, Fruits). ??? ()
}
How can I possibly get the fruit method with something similar to the function returnObjectFromName, if this is even possible?
I began the development with Python (independently), and there I can at least use eval(), but as I understand in C++ this is not an option.
I tried also with map, but I didn't manage to make it work with methods.
Thank you all for your answers.
Its not good way to rely on reflection in C++ and i think there is no way to list methods in classes. Maybe you can use function pointers but pointer to instance methods are hell.
I recommend to use polymorphism and good design. If some items might be taken, then use interface like this:
#include <iostream>
using namespace std;
class ITakeable {
public:
virtual bool isTakeable() = 0;
virtual void take() = 0;
virtual void cannotTake() = 0;
};
class fruit : public ITakeable {
public:
string actual_name;
fruit(string name){
actual_name = name;
}
bool isTakeable() {
return true;
}
void take() {
cout << "You take a " << actual_name << "." << endl;
}
void cannotTake() {
cout << "not needed to be implemented";
}
};
class airplane : public ITakeable {
public:
string actual_name;
airplane(string name){
actual_name = name;
}
bool isTakeable() {
return false;
}
void take() {
cout << "not needed to be implemented";
}
void cannotTake() {
cout << "You CANNOT take a " << actual_name << "." << endl;
}
};
int main() {
fruit apple("apple");
if (apple.isTakeable()) {
apple.take();
}
airplane plane("boeing");
if (plane.isTakeable()) {
plane.take();
} else {
plane.cannotTake();
}
// use of interface in general
ITakeable * something = &apple;
if (something->isTakeable()) {
something->take();
}
something = &plane;
if (something->isTakeable()) {
something->take();
} else {
something->cannotTake();
}
return 0;
}
Since fruit is a user defined type, you have to declare your own methods for your type or you inherit from one previously defined.
There are a lot of method for "built-in" string type
that Performs virtually the same job as eval (...) in python.
Also I noticed your function need not be defined independently outside of class fruit.
I want to be able to have the user enter their name, store it and be able to recall it in different functions. This is my first code, first program. I am sure there is an easier way to do this, so if you could offer both an answer to the question and a easier way of accomplishing this task it would be much appreciated. Thank you in advance.
This is what I have so far:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
using namespace std;
void game();
void other();
class NameClass{
public:
string name;
};
int main()
{
int a;
int age;
string name;
cout << "Hello user, what is you name? \n\n";
/*Not sure if class and operator needs to be here. I was hoping that when the user
input the stream(their name) it would be stored in the class as well as being able
to use it in the main function.*/
NameClass person;
//This line is here to get name from user.
getline(cin, name);
cout << "Well " << name << ", are you having a good day? \n\n";
cout << "1=Yes 2=No \n\n";
cin >> a;
cout <<"\n";
if(a==1){
cout << "Well that is good to hear.\n\n";
}else{
cout << "I am sorry to hear that. I hope things get better for you. \n\n";
}
cout << "Do you want to play a game? \n\n";
cin >> a;
if(a==1){
game();
}else{
other();
return 0;
}
return 0;
}
void game(){
/*It is in this function that I want the be able to recall the name that the user input in the main function.*/
cout << "Cool "<< name <<",let get started." << endl;
}
void other(){
cout << "Well then "<< name <<", lets do something else.";
}
I assume you aren't aware of the OOP concepts.
Do this (make methods part of the class):
class NameClass{
public:
string name;
void game();
void other();
};
int main()
{
...
NameClass person;
getline(cin, person.name);
...
}
Or this (pass name as parameter):
int main()
{
string name;
...
game(name);
}
void game(string name)
{
cout << "Cool "<< name <<",let get started." << endl;
}
If you want to pass information from one function to another then you use a function parameter (or more than one).
void game(string name);
int main()
{
string name;
...
game(name);
}
void game(string name)
{
cout << "Cool "<< name <<",let get started." << endl;
}
It's a fundamental concept that pretty much all programming languages have.
Just pass the name as a parameter in both your functions, it should be something like this:
//functions
void game(string name);
void other(string name);
In your main function when you call either function just pass the name to it.
if(a == 1)
{
game(name);
}
else
{
other(name);
}
I have the following files:
main.cpp
shop.hpp
player.hpp
With the following code in each of them:
main.ccp:
#include <iostream>
#include <cstdlib>
#include "shop.hpp"
using namespace std;
string *inventory= new string[3];
int invGold= 355;
int main(void){
shop store;
store.store();
}
shop.hpp:
#include <iostream>
#include <cstdlib>
using namespace std;
class shop{
public:
string shopOption;
string shopOptions[6]= {"Buy", "buy", "Sell", "sell", "Leave", "leave"};
string shopInv[3]= {"Sword", "Potion", "Arrows x 25"};
int shopInvAmount= sizeof(shopInv)/sizeof(shopInv[0]);
int shopPrices[3]= {250, 55, 70};
shop(){
cout << "Shopkeeper: We buy, we sell, what's your buisness?" << endl;
}
void store(void){
getline(cin,shopOption);
if(shopOption.compare(shopOptions[0]) == 0 || shopOption.compare(shopOptions[1]) == 0){
buy();
}
else if(shopOption.compare(shopOptions[2]) == 0 || shopOption.compare(shopOptions[3]) == 0){
sell();
}
else if(shopOption.compare(shopOptions[4]) == 0 || shopOption.compare(shopOptions[5]) == 0){
leave();
}
}
void buy(){
srand(time(0));
string buyQuotes[3]= {"What are you buyin', hon?", "Make it quick, I ain't got all day.", "Another day, another sell."};
int quotePick= rand() % sizeof(buyQuotes)/sizeof(buyQuotes[0]) - 1;
if (quotePick < 0){
quotePick= 0;
}
else if (quotePick > (sizeof(buyQuotes)/sizeof(buyQuotes))){
quotePick= sizeof(buyQuotes)/sizeof(buyQuotes);
}
cout << "TEST:" << sizeof(shopInv)/sizeof(shopInv[0]) << endl;
cout << buyQuotes[quotePick] << endl;
cout << "SHOP INVENTORY" << endl << "--------------" << endl;
cout << endl;
for (int i=0; i < sizeof(shopInv)/sizeof(shopInv[0]); i++){
cout << shopInv[i]<< ": " << shopPrices[i] << endl;
}
cout << endl << "What'll it be?:";
getline(cin,shopOption);
}
void sell(){
}
void leave(){
}
};
and player.hpp
class player{
public:
int playerHP= 18;
string playerInv[5] {};
int playerGold= 355;
};
Now, what i'd like to do, is that after the character selects the items they want to buy, and te amount of it, (Not programmed yet) check the price of the combined items, and see if the character has enough money on hand, and if the character buys the items, add them to the player's inventory.
But i'd like to keep the values the store uses, and everything related to the player in different class files.
Thing is, I have no idea how to pull something like that.
So, is t possible to access a class' variable from another class that is in another file althogether?
And if isn't, how would you suggest i get around this problem?
Start reading here: How does the compilation/linking process work? to get multiple files working for you. Odds are pretty good that whatever coding environment you are using will automate the process for you.
Then consider making an item class
class Item
{
public:
Item(string name, int price): mName(name), mPrice(price)
{
}
string getName()
{
return mName;
}
string getPrice()
{
return mPrice;
}
// other functions
private:
string mName;
int mPrice;
// other stuff
}
In Shop and Player, keep a list of Items
vector<Item> items;
When a Player tries to buy an item, find it in the list, ensure the Player can afford it, remove it from the Shop's list and add it to the Player's list.
I have a project for a class and I'm not sure what type of array I should be using for this program. I have to make a stock market program where the user buys, sells and views stock listings and checks their account balance. There are two text files that contain the following data:
Leon1111 5000.00
Wise2222 10000.00
Woo3333 3000.00
White4444 7000.00
Head5555 4000.00
and
Apple AAPL 450.00
Boeing BA 75.50
Intel INTC 22.30
Rambus RMBS 5.55
Sirius SIRI 3.15
Skyworks SWKS 25.35
Xilinx XLNX 36.80
This is the code I've written so far:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
ofstream outStream;
int option;
do
{
cout << "1) Check Stock Listings " << endl;
cout << "2) Buy Stock " << endl;
cout << "3) Sell Stock" << endl;
cout << "4) Check Account Balance " << endl;
cout << "5) Quit " << endl << endl;
cout << "Please select an option : ";
cin >> option;
cout << endl;
if (option == 1)
{
fstream CompaniesFile;
CompaniesFile.open("Companies.txt");
if (CompaniesFile.is_open())
{
string s;
while (getline(CompaniesFile, s, '\n'))
{
cout << s << endl;
}
}
CompaniesFile.close();
}
else if (option == 2)
{
}
else if (option == 3)
{
}
else if (option == 4)
{
fstream AccountFile;
AccountFile.open("Account.txt");
if (AccountFile.is_open())
{
string t;
while (getline(AccountFile, t))
{
cout << t << endl;
}
}
AccountFile.close();
}
else if (option == 5)
{
cout << "Program Terminated. Have a nice day!" << endl << endl;
}
else
{
cout << "Invalid Option entered" << endl;
}
}
while (option != 5);
return 0;
}
class cCompany
{
std::string myName;
std::string mySymbol;
double myPrice;
public:
cCompany( const std::string& name,
const std::string& symbol,
double price )
: myName( name ), mySymbol( symbol ), myPrice( price )
{}
};
std::vector< cCompany > vCompany;
class cAccount
{
std::string myName
double myBalance;
public:
cAccount( const std:string& name, double balance )
: myName( name ), myBalance( balance )
{}
};
std:vector< cAccount > vAccount;
...
std::string name;
std::string symbol;
double price;
while ( CompaniesFile.good() )
{
CompaniesFile >> name;
CompaniesFile >> symbol;
CompaniesFile >> price;
vCompany.push_back( cCompany( name, symbol, price ));
}
You are going to probably need a bit more than name and balance for an account holder, so if I had my druthers I would use a vector (or map) of a class for account holders. The account holder class would hold name, balance, and then a vector (or even better a map) of shares that the person holds and the number of shares. Something like:
class AccountHolder{
private:
std::string name_;
long long int balance_; //balance in cents
//to allow for something like buy("AAPL", 100);
// to be implemented as:
// void buy(std::string symbol, long int shares)
// {
// long int price = shares * sharePrice[symbol];
// if (balance_ >= price)
// {
// balance_ -= price;
// holdings_[symbol] += shares;
// } else
// throw(INSUFFICIENT_FUNDS);
// }
std::map<std::string, long long int> holdings_;
public:
...
};
For shares, I would use a map since you only need to know their name (and/or symbol) and the price. Maybe you can have the key be the symbol, and then the value to be price, and another map for symbol and full name. This way you can easily find the share prices: all you need to do is
std::cout << "price of a single share from " << fullName["AAPL"]
<< " is: " << sharePrice["AAPL"] << "\n";
Try to make your application more OO-like (Object Oriented). My suggestion is first you can create some data structures:
struct user { string name; double balance; }
struct stock { string name; double price; }
struct stockBought { string userName; string stockName; int share; }
then use something to save your data, for example,
list<user> users;
list<stock> stocks;
list<stockBought> stockBought;
then you should have a function to read from the two files
readUsersFromFile(users, fUsersFile);
readStocksFromFile(stocks, fStockFile);
then you should have a function to update the list
update(users, 3, 1, 4000.0); //update the users list: 3rd user, 1st column (5000.0 => 4000.0)
add(stockBought, "Leon1111", "AAPL", 1); //leon bought 1 share of AAPL
then you have to implement all the functions needed for the 5 options. Add more utility functions/classes as you move on.
Once you finish the 1st version. you can polish your code to make it run faster (adding index etc) or look better (better class).
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.