How to switch to a dynamic array? - c++

I'm trying to set the size of an array to an input received by the program, currently the size of the array is defined as a const static int.
Board.h
#include <iostream>
using namespace std;
class Board {
private:
const static int BOARDSIZE = 5;
char board[BOARDSIZE][BOARDSIZE];
const char p1Symbol = 'R';
const char p2Symbol = 'B';
const char trail = 'O';
const char crash = '*';
int p1Row;
int p1Col;
int p2Row;
int p2Col;
public:
void setBoardSize(int size);
bool isValidMove(int row, int col);
bool isValidInput(char input);
bool getNextMove();
void initializeArray();
void drawHorizontalSeparator();
void drawSeparatedValues(int row);
void displayBoard();
};
Main
#include <iostream>
#include "Board.h"
using namespace std;
int main() {
int size;
cout << "Enter and integer between 4 and 20 for the BoardSize: " << endl;
cin >> size;
Board b;
b.setBoardSize(size);
b.initializeArray();
b.displayBoard();
bool done = false;
while (!done) {
done = b.getNextMove();
}
return 0;
}
I'm trying to use this function called setBoardSize to change the size of the board in the Board.H file. I've tried removing const static but then I get all sorts of errors. Apparently it isn't possible to define an array that doesn't have a predefined size?

Instead of char board[BOARDSIZE][BOARDSIZE] go for std::vector<char>(BOARDSIZE * BOARDSIZE, 0) and access elements as vector[y * BOARDSIZE + x] where x and y run within <0, BOARDSIZE).
You would resize simply as vector.resize(size * size).

Related

problem passing array of struct to a function throwing undefined reference c++

I'm having issues with passing an array of structures to a function that searches them. I delcare an array of structs outside of main then copy it to a new array of structs inside of main (so I have access to them inside main and can pass them easier). Not sure why it is failing though. Can anyone help me?
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <algorithm>
using namespace std;
const int MAX = 2000000;
const string DFile = "DFile.dms";
const string EFile = "EFile.dms";
const string VFile = "VFile.dms";
struct dogs
{
int did;
int age;
} DFBuffer[MAX];
struct examine
{
int vid;
int did;
int fee;
} EFBuffer[MAX];
struct vet
{
int vid;
int eLevel;
} VFBuffer[MAX];
void readDF(ifstream&);
void readEF(ifstream&);
void readVF(ifstream&);
int getLineCount(ifstream&);
bool dogCompare(dogs lhs, dogs rhs) {return lhs.did < rhs.did;}
bool vetCompare(vet lhs, vet rhs) {return lhs.vid < rhs.vid;}
bool examCompare(examine lhs, examine rhs) {return lhs.vid < rhs.vid;}
void vetExamSeach(struct vet newVetArray[], struct examine newExamArray[],
int, int);
int main()
{
dogs * newDogArray = new dogs[MAX];
examine * newExamArray = new examine[MAX];
vet * newVetArray = new vet[MAX];
ifstream DF, EF, VF;
int dogCount = 0, examCount = 0, vetCount = 0;
DF.open(DFile);
readDF(DF);
EF.open(EFile);
readEF(EF);
VF.open(VFile);
readVF(VF);
DF.open(DFile);
dogCount = getLineCount(DF);
EF.open(EFile);
examCount = getLineCount(EF);
VF.open(VFile);
vetCount = getLineCount(VF);
for(int i = 0; i < dogCount; i++)
newDogArray[i] = DFBuffer[i];
for(int i = 0; i < vetCount; i++)
newVetArray[i] = VFBuffer[i];
for(int i = 0; i < examCount; i++)
newExamArray[i] = EFBuffer[i];
cout << "Sorting...\n";
sort(newDogArray, newDogArray + dogCount, dogCompare);
sort(newExamArray, newExamArray + examCount, examCompare);
sort(newVetArray, newVetArray + vetCount, vetCompare);
cout << "Sorting complete!\n";
vetExamSeach(newVetArray, newExamArray, vetCount, examCount);
return 0;
}
here is the search function. for the sake of this question, im just trying to print what i pass it.
void search(vet newVetArray[], examine newExamArray[], int vCount, int eCount)
{
for(int i = 1; i < vCount; i++)
cout << "in search: " << newVetArray[i].vid << ' ' << newVetArray[i].eLevel << endl;
}
here is the error I'm getting
Here is my files. Not asking you to do my HW just help me solve my issue
When, I run your code, I get the same compilation error of undefined reference for readDf, readEF, readVF, getLineCount and vetExamSeach.
The error is because there is no definition of these functions. There are only just decalarations. When I define them (something random) the errors are gone.
So, define the function(s) and the error(s) would be gone.

Pointers, Struct, C++,Writing a new structure in a function

Could someone explain me the following mistakes and tell me how to fix them (written as comments)?
The structure I have:
const int max = 1000;
const int MAX = 30;
struct student_t
{
int k;
char* name[MAX];
char** bez[MAX];
};
With this function I must write a member of this structure(members<=1000) and bez. (<=30) for every member:
int write (student_t *field[max], int i)
{
student_t *pointerfield= new student_t;
printf("Number:....");
std::cin>>pointerfield->number;
if (pointerfield->number>1 && pointerfield->k<999999)
{
if (binarsearch(&field[max],i,(pointerfield->number))!=-1)
{
return i;
}
else
{
printf("\nName:.....");
readstr();
pointerfield->name=readstr();
// insupportable types of allocation of int to char* [30]
std::cout<<std::endl;
int counter=0;
std::cout<<"Do you want to add bez.? j,n"<<std::endl;
char a;
std::cin>>a;
if(a=='j' && counter<MAX)
{
std::cout<<"Bez.:";
readstr();
pointerfield->bez[MAX]=readstr();
// char * can not be converted into assignment to char **
counter++;
}
// ...

Getting the "undefined reference to class::function" error on my C++ game.

I am programming this game for a university work and i believe that my code is right, but i keep getting this error and it is keeping me from finishing my work in time. So here's the game board class header:
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cstdio>
class CMagicAlchemistBoard
{
public:
CMagicAlchemistBoard(void); // Default Constructor
CMagicAlchemistBoard(const CMagicAlchemistBoard& board); // Copy Constructor
~CMagicAlchemistBoard(void ); // Destructor
void SetupBoard(void); // Function to setup the board
int GetBoardSpace(int row, int col); // Get the color at row,col
// Accessor functions to get/set board size information
int GetColumns(void) const { return m_nColumns; }
void SetColumns(int nColumns) { m_nColumns = (nColumns >= 6) ? nColumns : 6; }
int GetRows(void) const { return m_nRows; }
void SetRows(int nRows) { m_nRows = (nRows >= 8) ? nRows : 8; }
void DeleteBoard(void); // Function to delete the board and free memory
void ExecuteMove(int row, int col);
bool IsGameOver(void) const; // Is the game over?
void DrawBoard(void);
bool ValidMove(int row, int col); // Function to see if a move is valid
private:
void CreateBoard(void); //Function to create the board and allocate memory
// Class Data
int** m_arrBoard; // 2D array pointer
// Board size information
char m_arrChars[10];
int m_nColumns;
int m_nRows;
};
And here is the .cpp file with only the implementation of the DrawBoard() function:
#include "cmagicalchemistboard.h"
using namespace std;
void CMagicAlchemistBoard::DrawBoard(void)
{
cout << "MAGIC ALCHEMIST" << endl;
cout << " ";
for(int col = 0; col < m_nColumns; col++){ printf(" ---",col); }
cout << endl;
for(int row = 0; row < m_nRows; row++)
{
for(int col = 0; col < m_nColumns; col++)
{
cout << "| " << m_arrChars[GetBoardSpace(row, col)];
}
cout << "| " << endl;
}
}
I pretend to use this function on another class. Here's the header of that class:
#include "cmagicalchemistboard.h"
#include <iostream>
#include <cstdlib>
#include <conio.h> //Contains the function getch(), which reads the input from the keyboard
#define LEFT_ARROW 75
#define RIGHT_ARROW 77
#define UP_ARROW 72
#define DOWN_ARROW 80
#define ESC 27
class CMagicAlchemist
{
public:
CMagicAlchemist();
~CMagicAlchemist();
// Functions for accessing the game board
char GetBoardSpace(int row, int col) { return m_board->GetBoardSpace(row, col); }
void SetupBoard(void) { m_board->SetupBoard(); }
int GetColumns(void) { return m_board->GetColumns(); }
void SetColumns(int nColumns) { m_board->SetColumns(nColumns); }
int GetRows(void) { return m_board->GetRows(); }
void SetRows(int nRows) { m_board->SetRows(nRows); }
void DeleteBoard(void) { m_board->DeleteBoard(); }
bool IsGameOver() { return m_board->IsGameOver(); }
void InputGameParameters();
void GetMove(int &row, int &col);
void DrawBoard();
void NewGame();
void Game();
private:
CMagicAlchemistBoard* m_board; // Instance of the game board
int m_nmoves;
};
And finally, the .cpp file of this last class with only the implementation of the function that calls the DrawBoard() function:
#include "cmagicalchemist.h"
void CMagicAlchemist::Game()
{
int x,y;
InputGameParameters();
NewGame();
DrawBoard();
}
So, my problem is: when i compile this program im getting this error: "undefined reference to CMagicAlchemist::DrawBoard()". This is stupid because the DrawBoard() function doesnt even belong to CMagicAlchemist class but instead, it belong to CMagicAlchemistBoard class. Can somebody help me?
You have DrawBoard declared in your CMagicAlchemist class.
You call DrawBoard from a CMagicAlchemist member function.
That tries to call Drawboard for the CMagicAlchemist class.

c++ Expression: string subscript out of range

When I try debugging the code, it runs into the debugging error "c++ Expression: string subscript out of range"
Pretty sure the problem was brought while calling setCode().
How do I fix the code inside setCode()?
#include <iostream>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <list>
using namespace std;
class test
{
private:
string code;
int digit;
public:
//constructor
test(): code(""), digit(0) { }
//copy constructor
test(const test &other):
digit(other.digit)
{
for(unsigned int i=0; i < code.length(); i++)
code[digit] = other.code[digit];
}
//set up the private values
void setCode(const string &temp, const int num);
void setDigit(const int &num);
//return the value of the pointer character
const string &getCode() const;
const unsigned int getDigit() const;
};
const string& test::getCode() const
{
return code;
}
const unsigned int test::getDigit() const
{
return digit;
}
void test::setCode(const string &temp, int num)
{
code[num] = temp[num];
}
void test::setDigit(const int &num)
{
digit = num;
}
int main()
{
string contents = "dfskr-123";
test aisbn;
list<test> simul;
list<test>::iterator testitr;
testitr = simul.begin();
int count = 0;
cout << contents << '\n';
aisbn.setCode(contents, count);
aisbn.setDigit(count);
simul.push_back(aisbn);
count++;
/*for(; testitr !=simul.end(); simul++)
{
cout << testitr->getCode() << "\n";
}*/
}
When you create an instance of the test class, the string inside it is empty. This means that whenever you do e.g. code[something] you will be out of range. It doesn't matter what the index is.
You either need to set the string to a certain length from the start, and make sure that the index is within the range. Or to make sure that the index is within range by dynamically extending the string when needed.
You have to make sure that when this statement executes:
code[num] = temp[num];
both code and temp are at least of size num + 1.

C++ object member integer has ridiculous value (WTF)

This is for a poker game and I have class PokerTable defined in PokerTable.h
#include <iostream>
using namespace std;
class PokerTable
{
private:
int numPlayers;
int numPlaying;
int dealerPos;
int bigBlind;
int potSize;
int betSize;
bool flop;
bool turn;
bool river;
public:
//constructors
PokerTable();
PokerTable(int,int,int,int,int,bool,bool,bool);
//getters
int getNumPlayers(){return numPlayers;};
int getDealerPos(){return dealerPos;};
int getBigBlind(){return bigBlind;};
int getNumPlaying(){return numPlaying;};
int getPotSize(){return potSize;};
int getBetSize(){return betSize;};
bool getFlop(){return flop;};
bool getTurn(){return turn;};
bool getRiver(){return river;};
//void buttonShow(int);
//setters
void setBetSize(int inBetSize){betSize = inBetSize;};
void setBigBlind(int inBigBlind){bigBlind = inBigBlind;};
void setNumPlaying(int inNumPlaying){numPlaying = inNumPlaying;};
void setPotSize(int inPotSize){potSize = inPotSize;};
void setFlop(bool inFlop){flop = inFlop;};
void setTurn(bool inTurn){turn = inTurn;};
void setRiver(bool inRiver){river = inRiver;};
void setNumPlayers(int inPlayers){numPlayers = inPlayers;};
void setDealerPos(int inDealerPos){dealerPos = inDealerPos;};
};
PokerTable::PokerTable()
{
numPlayers = 9;
numPlaying = 9;
dealerPos = 1;
bigBlind = 20;
flop = false;
turn = false;
river = false;
}
PokerTable::PokerTable(int playerNum, int playingCount, int posDealer, int blindBig,int inPotSize, bool inFlop,bool inTurn,bool inRiver)
{
numPlayers = playerNum;
numPlaying = playingCount;
dealerPos = posDealer;
potSize = inPotSize;
bigBlind = blindBig;
flop = inFlop;
turn = inTurn;
river = inRiver;
}
In my watch list pokerTable.numPlayers has a random value up to 4 million before I even execute this next line of code.
PokerTable aPokerTable(9,9,1,20,30,false,false,false);
and afterwards here is pokerTable in my watch list:
- aPokerTable { numPlayers=2990892 numPlaying=9 dealerPos=9 ...} PokerTable
betSize 30 int
bigBlind 1 int
dealerPos 9 int
flop false bool
numPlayers 2990892 int
numPlaying 9 int
potSize 20 int
river false bool
turn false bool
Can anyone tell me why all the values are not what I declared them to be??!?!!
And how I can fix this?
This is Form1.h
#pragma once
#include "PokerTable.h"
#include "Card.h"
#include <time.h>
#include "PokerPlayer.h"
#include <fstream>
#include <string>
#include <sstream>
//global variables
//TODO make players start from 0
int firstPlayer;
int deck[52];
int nextCard=0;
PokerTable aPokerTable(9,9,1,20,30,false,false,false);
PokerPlayer players[9]; //however many players
ofstream gameLog;
/*
void setTable()
{
aPokerTable.setNumPlayers(9);
aPokerTable.setNumPlaying(9);
aPokerTable.setDealerPos(1);
aPokerTable.setBigBlind(20);
aPokerTable.setPotSize(30);
aPokerTable.setBetSize(20);
aPokerTable.setFlop(false);
aPokerTable.setTurn(false);
aPokerTable.setRiver(false);
}
*/
string convertInt(int number) //convert to string
{
stringstream ss;//create a stringstream
ss << number;//add number to the stream
return ss.str();//return a string with the contents of the stream
}
void createPlayers()
{
// aPokerTable.setNumPlayers(9);
for(int x=0;x<=(aPokerTable.getNumPlayers()-1);x++)
{
players[x] = *(new PokerPlayer(1000,(aPokerTable.getDealerPos())+1,false,0,1));//1000 chips, position i+1, not folded
}
}
void playRound()
{
int action;
for(int playerTurn = firstPlayer; playerTurn <= aPokerTable.getNumPlayers()+firstPlayer; playerTurn++)
{
if(players[playerTurn].getFold() == false)
{
if(aPokerTable.getNumPlaying() == 1)
{
players[playerTurn].setChipStack(players[playerTurn].getChipStack() + aPokerTable.getPotSize()); //player wins pot
}
else //there is more than one person playing
{
action = players[playerTurn].action(); //0 is check/fold, value is call/bet/raise,
if(action > aPokerTable.getBetSize())
{
aPokerTable.setBetSize(action);
aPokerTable.setPotSize(aPokerTable.getPotSize() + action);
playerTurn = playerTurn - aPokerTable.getNumPlayers();
}
else if (action == aPokerTable.getBetSize()) //call
{
aPokerTable.setPotSize(aPokerTable.getPotSize() + action);
}
else //action < aPokerTable.betSize
{
players[playerTurn].setFold(true);
aPokerTable.setNumPlaying(aPokerTable.getNumPlaying()-1); //removes player from playing tally
}
}
}
}
}
void randomDeck()
{
int random_integer;
int tempCard;
//srand((unsigned)time(0));
for(int j=0;j<=51;j++)
{
deck[j] = j;
}
for(int i=51; i>=1; i--)
{
random_integer = rand()%(i); //a random number between 0 and i
tempCard = deck[i];
deck[i] = deck[random_integer]; //put the random card from unshuffled deck into slot i of the deck
deck[random_integer] = tempCard; //put whatever was at slot i into the random slot
}
}
void dealCards()
{
for(int j=1;j<=aPokerTable.getNumPlayers();j++)
{
players[j].setCard1(deck[nextCard]);
nextCard++;
players[j].setCard2(deck[nextCard]);
nextCard++;
}
}
void playPreFlop()
{
aPokerTable.setBetSize(aPokerTable.getBigBlind());
aPokerTable.setFlop(false); //it is before the flop
aPokerTable.setTurn(false);
aPokerTable.setRiver(false);
randomDeck(); //shuffle cards
dealCards();
firstPlayer = (aPokerTable.getDealerPos() + 3)%(aPokerTable.getNumPlayers()); // first player is left of blinds between 0 and numplayers
playRound();
}
void playFlop()
{
aPokerTable.setFlop(true);
firstPlayer = (aPokerTable.getDealerPos())%aPokerTable.getNumPlayers(); // first player is left of dealer between 0 and numplayers
aPokerTable.setBetSize(0);
playRound();
}
void playTurn()
{
aPokerTable.setTurn(true);
firstPlayer = (aPokerTable.getDealerPos())%aPokerTable.getNumPlayers(); // first player is left of dealer between 0 and numplayers
aPokerTable.setBetSize(0);
playRound();
}
void playRiver()
{
aPokerTable.setRiver(true);
firstPlayer = (aPokerTable.getDealerPos())%(aPokerTable.getNumPlayers()); // first player is left of dealer between 0 and numplayers
aPokerTable.setBetSize(0);
playRound();
if(aPokerTable.getNumPlaying() >=2)
{
//showDown();
}
}
/*
void showDown()
{
}
*/
This is pokerPlayer.h
using namespace std;
class PokerPlayer
{
private:
int chipStack,position;
bool fold;
int card1,card2;
public:
//constructors
PokerPlayer();
PokerPlayer(int,int,bool,int,int);
//getters
int getChipStack() {return chipStack;}
int getPosition() {return position;}
int getCard1(){return card1;}
int getCard2(){return card2;}
bool getFold(){return fold;}
//setters
void setChipStack(int inChips){chipStack = inChips;}
void setPosition(int inPos){position = inPos;}
void setCard1(int inCard1){card1 = inCard1;}
void setCard2(int inCard2){card2 = inCard2;}
void setFold(bool inFold){fold = inFold;}
int action();
};
PokerPlayer::PokerPlayer()
{
chipStack = 1000;
position = 0;
fold=false;
card1 = 0;
card2 = 1;
}
PokerPlayer::PokerPlayer(int inChipStack,int inPos, bool inFold, int inCard1, int inCard2)
{
chipStack = inChipStack;
position = inPos;
fold = inFold;
card1 = inCard1;
card2 = inCard2;
}
int PokerPlayer::action()
{
return 0;
}
aPokerTable { numPlayers=2990892 numPlaying=9 dealerPos=9 ...}
Note that dealerPos got assigned the value 9, that's wrong as well. If you look closely, you'll see that everything is shifted by 4 bytes.
Two possible reasons. The debugger could have picked the wrong address for aPokerTable, the actual address minus 4. That's unlikely. Or there's a mismatch between the definition of the PokerTable class as seen by pokertable.cpp and the other .cpp files that #include the pokertable.h include file. Where pokertable.cpp saw an extra member before the numPlayers member. Maybe you edited the header and deleted that member but ended up not recompiling pokertable.cpp for some mysterious reason. Build + Rebuild to fix. Do panic a bit if this actually works.
It's because in C++ before the constructor is called, variable uses the value that it already contains in its memory location that is a "random" value
I cannot reconstruct it because i dont have the full code. However, a random value near 4 million sounds like a pointer. When you store or retrieve a member variable maybe you did not de-reference the pointer. Please post the rest of the code so we can check if that's the case.
players[x] = *(new PokerPlayer(...));
That is a memory leak. What you probably want is:
players[x] = PokerPlayer(1000,(aPokerTable.getDealerPos())+1,false,0,1);