Passing array off as reference in c++ without using pointer - c++

I have a quick question regarding an assignment I have to complete for C++. The teacher has required that I include the functions below:
void getPlayerInfo(Player &);
void showInfo(Player);
int getTotalPoints(Player [], int);
But I'm having trouble working on the first function....I'm not sure if I'm calling the array of structures properly. Can someone look it over and see what I'm doing wrong? I fiddled with it a bit and I'm able to call the array and pass off a pointer to the array but the teacher requested the "&" symbol be there so there must be another method I'm unaware of. Please help! Thanks
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
// Structure to hold information about a player
struct Player
{
string name; // to hold the players name
int number; // to hold players number
int points; // to hold the points scored by the player
};
// Function prototypes
void getPlayerInfo(Player &); // function to get the players information from the user
void showInfo(Player); // function to show the table
int main()
{
const int numPlayers = 12; // Constant to hold the number of players
Player team[numPlayers]; // array to hold 12 structures
// Gather information about all 12 players
getPlayerInfo(team);
showInfo(team);
return 0;
}
// Function to get the players info
void getPlayerInfo(Player& team)
{
for (int count = 0; count < 12; count++)
{
cout << "PLAYER #" << (count + 1) << endl;
cout << "----------" << endl;
cout << "Player name: ";
cin.ignore();
getline(cin, team[count].name);
cout << "Player's number: ";
cin >> team[count].number;
cout << "Points scored: ";
cin >> team[count].points;
cout << endl;
}
}

getPlayerInfo() does not accept an array, it accepts a reference to a single Player object.
You need to call getPlayerInfo() for each player in your array. Move your loop outside of getPlayerInfo() and into main().

You've misunderstood the intent of these functions.
Guessing from the information you've provided, getPlayerInfo is intended to get the information of an individual player, and showPlayerInfo is intended to show the information of an individual player.
You're trying to use these functions to do something they aren't intended to do, so it's a good thing that you are having trouble figuring out how to call and how to implement them.
Consider this experience as a object lesson in requirement gathering.

Related

Can I add a different function that is defined in my code in a vector like arrays that include function adress?

In this code, there are 6 different functions. They create 6 different boards for playing a game. But I don't want to create boards with if conditions, I want to create a vector that includes function addresses in it. For example, if the user wants to create board 4 for playing the game, I want to create the board like this:
vector<vector<cell>> a = function_array[3];
cell is an enum type that I declared.
Can I do this, and can somebody help me for this?
vector<vector<cell>> first_table();
vector<vector<cell>> second_table();
vector<vector<cell>> third_table();
vector<vector<cell>> fourth_table();
vector<vector<cell>> fifth_table();
vector<vector<cell>> sixth_table();
int main()
{
int chose,board_type;
vector<vector<vector<cell>>> functions;
functions.push_back(first_table());
functions.push_back(second_table());
functions.push_back(third_table()); //in here I create all boards and print which one the user wants
functions.push_back(fourth_table()); //but I don't want to do this, I want just create the board the user wants
functions.push_back(fifth_table());
functions.push_back(sixth_table());
vector<vector<cell>> b = functions[board_type-1];
print_game(b);
b = functions[0];
cout << "welcomw Game" << endl;
cout << "Please chose board type" << endl;
cin >> board_type;
int game_type;
cout << "1.Personal game " << endl << "Computer game" << endl;
cin >> game_type;
string input;
cout << "Please enter move direction" << endl;
cin >> input;
}
What you are looking for is std::function
In your case, you'd create a vector of std::function<> for functions that take no parameter and return a vector<vector<cell>>.
#include <functional>
#include <vector>
struct cell {};
//type aliases make code a lot more readable!
using board = std::vector<std::vector<cell>>;
board first_table();
board second_table();
board third_table();
board fourth_table();
board fifth_table();
board sixth_table();
int main() {
std::vector<std::function<board()>> functions;
functions.push_back(first_table);
// etc...
board b = functions[board_type-1]();
}

My homework assignment requires me to use booleans in functions. Do I need to pass them to the functions?

For my homework assignment I'm supposed to make a create-your-own-adventure story. There are certain words in the text that are in all caps to represent boolean values that I need to display at the end if the player got them, like a status effect or something. I'm having trouble figuring out how to pass the booleans to the functions so that it makes it to the end of the program where I can display it. My program has functions within functions.
I've tried making the function that sets the boolean to true a boolean itself, then returning the boolean but that just ends the program it seems. I've also tried passing it through the first function call to see if it reaches the second but it doesn't seem like it wants to.
void A1();
bool A100(bool INTIM);
void A167();
void A232();
void A290();
void A13();
void A212();
void A173();
void A159();
void A161();
int main() {
bool INTIM;
A1();
cout << INTIM << endl;
return 0;
}
void A1()
{
int choice;
cout << "Well, Mr Artanon, ...\n 1. ’It’s you who’ll get a rare cut
across that corpulent neck of yours if you don’t speed things along, you
feckless blob of festering lard.’\n 2. ’Surely in such an industrious
kitchen, there must be a starter or two ready to send along and sate His
Abhorentness’s appetite?’\n (enter a menu option): ";
cin >> choice;
while (choice != 1 && choice != 2)
{
cout << "Enter in a valid choice (1 or 2)";
cin >> choice;
}
if (choice == 1)
{
A100();
}
if (choice == 2)
{
A167();
}
}
bool A100(bool INTIM)
{
int choice;
INTIM = true;
cout << " Repugnis turns a paler...\n 1. Onwards, Mr Artanon.\n (enter
in a menu option): ";
cin >> choice;
while (choice != 1)
{
cout << "Enter in a valid option (1)";
}
return INTIM;
A232();
}
What I'm wanting to happen is, the bool INTIM to be passed along so i can display it back in main with the cout statement. I know it will just be a 1 or 0 at the end but I'm just trying to get it to show up at least in the end when I display it. Again there are functions within functions in this program and that might be my problem but I wouldn't think so. There is also functions that come after this, this is not the end of the program and if I need to post the whole thing I will
Calling A100 as written, you need to pass in INTIM and accept the return value
INTIM = A100(INTIM);
But... The initiqal state of INTIM is never used, so you could
INTIM = A100();
and change A100 to look more like
bool A100()
{
int choice;
cout << " Repugnis turns a paler...\n 1. Onwards, Mr Artanon.\n (enter in a menu option): ";
cin >> choice;
while (choice != 1)
{
cout << "Enter in a valid option (1)";
cin >> choice; // added here because otherwise choice never changes
// and this loop will go on for a long, long time.
}
A232(); // moved ahead of return. Code after a return is not run
return true;
}
But since A232 is called and may set additional flags you cannot return, you have a design flaw: What if A232 also modifies a boolean? You can only return one thing from a function. You could pass A232's boolean in by reference, but what it A232 then calls B484 and it also has a boolean?
You don't want to have to pass around every possible boolean, that would be a confusing mess, so consider making a data structure that stores all of your booleans to pass around.
And that leads to an even better idea: encapsulating the booleans and the functions in the same data structure so that you don't have to pass anything around; it's all in the same place.
Do I need to pass them [the boolean results] to the functions?
Often, but not always, it is my preference to pass them by reference, and yes, it can get to be a big chain thru many functions. sigh.
But your question is "Do you need to pass them ...".
The answer is No.
Because
a) you have tagged this post as C++, and
b) the key feature of C++ is the user-defined-class.
Consider declaring every 'adventurous function' of your story within a class scope.
Each 'adventurous function', as an attribute of the class, is implemented with one 'hidden' parameter, the 'this' pointer to the class instance.
So .. if you place all your 'result' booleans as data attributes of the class, invoking any 'adventurous function' will also 'pass' all the class instance data attributes (all your bools!) as part of the invocation. No data is actually moving, just a pointer, the 'this' pointer.
It might look something like this:
#include <iostream>
using std::cout, std::cerr, std::flush, std::endl;
// using std::cin;
#include <iomanip>
using std::setw, std::setfill;
#include <sstream>
using std::stringstream;
#include <string>
using std::string;
namespace AS // Adventure Story
{
class CreateYourOwnAdventureStory_t
{
private:
// diagnostic purposes
stringstream ssUI;
// command line arguments concatenated into one string
// contents: strings convertable to ints to mimic cin
bool INTIM;
// other results go here
public:
int operator()(int argc, char* argv[]) {return exec(argc, argv);}
private:
int exec(int argc, char* argv[])
{
int retVal = 0;
// capture all command line arguments into a string
for (int i=1; i<argc; ++i)
ssUI << argv[i] << " ";
cout << "\n ssUI: " << ssUI.str() << "\n\n\n";
A1();
cout << "\n INTIM : " << INTIM << endl;
// ?more here?
return retVal;
}
void A1()
{
int choice = 0;
cout << "Well, Mr Artanon, ...\n "
"\n 1. ’It’s you who’ll get a rare cut across that corpulent neck of yours "
"if you don’t speed things along, you feckless blob of festering lard. "
"\n 2. ’Surely in such an industrious kitchen, there must be a starter or two "
"ready to send along and sate His Abhorentness’s appetite?’"
"\n (enter a menu option): ";
ssUI >> choice; // cin >> choice;
if (choice == 1) { A100(); }
if (choice == 2) { A167(); }
}
void A100()
{
int choice = 0;
INTIM = true;
ssUI >> choice; // cin >> choice;
cout << "\n\n A100() choice:" << choice
<< " INTIM: " << INTIM << endl;
}
void A167()
{
int choice = 0;
INTIM = false;
ssUI >> choice; // cin >> choice;
cout << "\n\n A167() choice:" << choice
<< " INTIM: " << INTIM << endl;
}
// other action-functions go here
}; // class CreateYourOwnAdventureStory_t
typedef CreateYourOwnAdventureStory_t CreateYOAS_t;
} // namespace AS
int main(int argc, char* argv[]){return AS::CreateYOAS_t()(argc,argv);}
Notes:
This example grabs the command line parameters and appends them to a string stream. The result is use-able in a fashion much like your cin statements.
Did you notice you (probably) will not need forward declarations for your functions? The compiler has to scan a lot of the class declaration to decide various issues, and thus can figure out that A100 (and A167) are actually with-in the scope of AS::CreateYOAS_t::. The functions can still be moved into a cpp file, so you can still take advantage of separate compilation. (and maybe save some effort compiling smaller files, and only the changed files.)
Did you notice that the functions accessing INTIM simply use the bool, without needing any 'this->' to de-reference?
Main invokes a simple Functor. Nothing else. Main invokes operator(). Simple, minimal. The ctor and dtor are currently default. If you need to use the ctor to initialize results or other intermediate info, I would simply add it near the operator() implementation.
PS: You mentioned using bools to return results. You might as, an alternative, consider using a stringstream ... a single stream with text ... use like a log for capturing the ongoing game, or for a single simple overall report to the user.
Good luck.

My Vector is not printing despite print function [duplicate]

This question already has answers here:
How to pass objects to functions in C++?
(8 answers)
Closed 3 years ago.
I am working on a program that will establish a class of a Combo meal with specific parameters for the objects. I am storing these in a vector. The vector appears to be running appropriately but when I use the print function it is not printing anything. I need help getting the print function to operate appropriately.
I have tried using the .at() instead of getEntree() but still am not receiving any output. I have read several pieces on here about printing from a vector and still am unable to get any output from my program.
#include <iostream>
#include <string>
#include <vector>
#include "Combo.h"
void fillOrder(vector<Combo>);
void printOrder(vector<Combo>);
int main()
{
vector<Combo> myOrder;
fillOrder(myOrder);
printOrder(myOrder);
}
vector<Combo> newMyOrder;
void fillOrder(vector<Combo> newMyOrder) {
string entree;
string side;
string sideSize;
string drink;
string drinkSize;
cout << "How many meals would you like to order? ";
int orderSize;
cin >> orderSize;
for (int i=0; i < orderSize; i++) {
cout << "Would you like a Hamburger, Cheeseburger, or chicken?" << endl;
cin >> entree;
cout << "Would you like fries, tots, or a salad for your side?" << endl;
cin >> side;
cout << "What size would you like your side?" << endl;
cin >> sideSize;
cout << "What would you like to drink?" << endl;
cin >> drink;
cout << "What size drink would you like?" << endl;
cin >> drinkSize;
Combo newMeal(entree, side, sideSize, drink, drinkSize);
newMyOrder.push_back(newMeal);
}
}
void printOrder(vector<Combo>newMyCombo) {
unsigned int size = newMyCombo.size();
for (unsigned int i = 0; i < size; i++) {
cout << "Your Entree is : " << newMyCombo[i].getEntree()<<endl;
cout << "Your side is : " << newMyCombo[i].getSide()<<endl;
}
}
I am wanting this program to take the order then print a summary of the order, but I am getting no output at all.
Pass by reference
Try:
void fillOrder(vector<Combo>&);
void fillOrder(vector<Combo>& newMyOrder)
If you'd want the print function to not work on a copy (as it is just printing the orders) use void printOrder(const vector<Combo>&); instead. The const qualifier will give you a compile guarantee that a function that should not modify the container does not really do that. Passing this by reference to print will ensure that you don't waste time and space in copying the whole thing.

C++ pass empty vector of structs to a function

I am trying to pass an empty vector of structures to a function which will read from a file and it will return the number of records read -- it will be an integer.
I initialize the vector of structures in main and when I attempt to pass it to the function as I would regularly do it:
int read_records(vector<player> player_info)
It gives me a "player is undefined" error. I have found a way to go around it as you will see in my code below but logic leads me to believe that there should be a way to pass the empty vector without having to fill in the first subscript.
The code is below. Please note that the read function is not yet complete as I am still wondering about the vector of structs.
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <fstream>
using namespace std;
//function prototypes
int read_records(struct player* player_info);
/*
* Define a struct called player that will consist
* of the variables that are needed to read in each
* record for the players. 2 strings for the first
* and last names and 1 integer to hold the statistics
*/
struct player
{
string first;
string last;
int stats;
};
int main(void)
{
int sort_by, records_read;
vector<player> player_info(1);
player * point = &player_info[0];
cout << "Welcome to Baseball player statistics program!" << endl;
cout << "How should the information be sorted?" << endl;
cout << "Enter 1 for First Name" << endl;
cout << "Enter 2 for Last Name" << endl;
cout << "Enter 3 for Points" << endl;
cout << "Enter your selection: ";
cin >> sort_by;
//read the records into the array
records_read = read_records(point);
system("Pause");
return 0;
}
int read_records(struct player* player_info)
{
//declare the inputstream
ifstream inputfile;
//open the file
inputfile.open("points.txt");
//handle problem if the file fails to open for reading
if (inputfile.fail())
{
cout << "The player file has failed to open!" << endl;
exit(EXIT_FAILURE);
}
else
{
cout << "The player file has been read successfully!" << endl;
}
return 5;
}
Define the type player before you attempt to declare functions that need to know about that type.
struct player
{
string first;
string last;
int stats;
};
int read_records(vector<player> player_info);
Your workaround was successful because naming player in struct player* acts as a [forward] declaration, in a way that naming it in vector<player> does not. (The whys and wherefores of this are too broad for this answer and are covered elsewhere on SO and in your C++ book.)
As an aside, I doubt you want to take that vector by value.
Why don't you put struct player definition before int read_records(vector<player> player_info).

Properly Store Object in Vector

I'm brand new to C++, and this is my first time posting (recipe for disaster). I've spent about a day trying to resolve my problem/question, in the mean time finding no easily recognizable solution on the forums. It's possible that my question has already been asked or that a solution has already been posted but I've overlooked it or misunderstood it. A similar post exists here, but it's not obvious to me what to do with the information.
I'll provide a concise, high-level summary of the point of this code. I'll then ask the specific question(s) to which I'm unable to find an answer, and I'll follow with the code I've written.
SUMMARY: I'm creating a program to help do bookkeeping for a game. The game may have any number of players, and each player having a small list of attributes/members (e.g. playerName, playerAllegiance, etc.) which are elements of a Player class/object. The user is first asked to input the name of each player (enteredName), and the program must create a new Player object for each name that's entered. This seems to be appropriately handled by a dynamic array, so I chose to use a vector (called playerIndex) to store each Player object. A for-loop allows the user to input names, each name instantiating a new Player object which is to be stored (copied?) into playerIndex using vector::push_back. At the conclusion of the for-loop, the user should be left with a vector of Player objects, each Player object storing a name in its playerName member.
QUESTION/PROBLEM: The code seems to work proprly when monitoring the vector inside the aforementioned for-loop. Immediately after the user enters the Nth player's name, the program spits out the playerName string stored in the Nth element of playerIndex using a Player class function getPlayerName() [actual code: playerIndex[playerCounter].getPlayerName()]. As soon as the user enters a blank playerName (i.e. presses enter without entering a name), it indicates the user has entered all player names, so the for-loop terminates. Just after this loop, a loop which is designed to output the playerName of each Player object stored in playerIndex does not output the expected names. I don't know why this is happening, but based on my very minimal knowledge of constructors, I'm guessing it has something to do with a copy or move constructor for the Player class. Can anyone clearly explain how to handle this issue? I fear I may be making a pitifully stupid, novice mistake and/or misunderstanding a key concept of C++.
CODE: This code is cropped/simplified to be as clear as possible. For example, the Player class is shown to have only one member (playerName) while, in the original code, it has four or five other members.
//HeaderPlayerClass.hpp
#include <iostream>
#include <string>
#ifndef PLAYERCLASS_HPP
#define PLAYERCLASS_HPP
using std::string;
class Player {
private:
string *playerName;
public:
Player();
Player(string);
~Player();
string getPlayerName();
};
#endif
//PlayerClass.cpp
#include "HeaderPlayerClass.hpp"
#include <iostream>
#include <string>
using std::string;
Player::Player() {
playerName = new string;
}
Player::Player(string enteredName) {
playerName = new string;
*playerName = enteredName;
}
Player::~Player() {
delete playerName;
}
string Player::getPlayerName() {
return *playerName;
}
//main.cpp
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include "HeaderPlayerClass.hpp"
using std::cin;
using std::cout;
using std::string;
using std::vector;
int main(int argc, char** argv) {
string buffer;
vector<Player> playerIndex;
int playerCounter = 0;
for(;;) {
if(playerCounter==0) {
cout << "\nEnter player name and press enter; leave blank and press enter to continue.\n";
}
cout << "\nPlayer " << playerCounter+1 << ":";
getline(cin, buffer);
if(buffer == "esc") {
cout << "PROGRAM EXITED BY USER\n";
return 0;
}
if(buffer.empty()) {
break;
}
playerIndex.push_back(Player(buffer));
cout << "Player " << playerCounter+1 << "'s name:" << playerIndex[playerCounter].getPlayerName() << "\n";
++playerCounter;
}
for(int ii = 0 ; ii < playerIndex.size() ; ii++) {
cout << "\nThis should display player " << ii+1 << "'s name:" << playerIndex[ii].getPlayerName();
}
return 0;
}
class Player {
private:
string *playerName;
Do not store a pointer to the string, store the string itself
class Player {
private:
string playerName;
Constructor
Player::Player() {
playerName = new string;
}
This is unnecessary if you store the string itself - the default constructor will initialize it for you.
Here is where the problems start - this will leave you vulnerable to memory leaks unless you carefully write a destructor
Player::Player(string enteredName) {
playerName = new string;
*playerName = enteredName;
}
All you need, if you store the string itself:
Player::Player( const string& enteredName)
: playerName ( enteredName )
{}
You constructor is really scary. Just leave things to the default destructor when you store the string itself
Player::~Player() {
delete playerName;
}
Next, you are working too hard keeping your own counter. std::vector maintains its own count and using
playerIndex.size()
will save trouble and bugs