access to array elements from different function but same class - c++

I have class that contains some functions with an array. One of them called pick, this function does not has an array but i want to display array element from other function, once i write code to display array element i can not get the element, although the code work and if i add normal text it will display but can not display array elements, i will attach the code below:
Note i did not attache full code only important parts
#include <iostream>
#include<stdlib.h>
#include <string>
using namespace std;
// global variable
string plantType;
int temperatures ;
string water;
string sunExposure;
bool pet;
string plant1,plant2,plant3;
class inside{
public:
void low(){
string plant1 [3]={"Snake plant","Spider plant","Aloe Vera plant"};
for(int i =0; i<3; i++){
cout << "* "<< plant1[i]<<endl;
}
}
void medium(){
string plant2 [5]={"Pothos plant","Dracaena plant","ZZ plant","Rubber plant","Philodendron Green plant"};
for(int i =0; i<5; i++){
cout << "* "<< plant2[i]<<endl;
}
}
void high(){
string plant3 [2]={"Bird’s Nest Fern plant","Peace Lily plant"};
for(int i =0; i<2; i++){
cout << "* "<< plant3[i]<<endl;
}
}
void pick(){
cout <<"Best choice for you is: ";
if (temperatures >= 13 && temperatures <=29 ){
if(water=="low"){
if(sunExposure=="fully"){
cout<<"test"<<endl;
if(pet==true){
cout<<plant1[1]<<endl; //this line cannot be executed
}
}
}}}
int main(){
cout <<"Where do you want to grow the plant (inside), or (outside)"<<endl;
cin>>grow;
if (grow == "inside"){
//inside home
cout<<endl<<"inside"<<endl;
cout<<"Enter the Temperature in (Celsius scale 13-29)"<<endl;
cin>>temperatures;
cout<<"Enter water level (low - medium - high)"<<endl;
cin>>water;
cout<<"Enter Sun Exposure (fully - partly - shady)"<<endl;
cin>>sunExposure;
cout<<"Do you have pet (true or false)? "<<endl;
cin>>pet;
inside inside;
inside.pick();
}
}

The string variables plant1[3], plant2[3] & plant3[3] are only visible to low(), medium(), high() but they're not for each other. For example, you're something trying to access a locally declared variable of foo() function in bar() function, which is impossible.
Secondly, you're trying to access plant1[3] data member in pick() but compiler doesn't know where you've actually defined those three plants' name outside of that function, just it knows plant1 variable with no arrays which is declared in the private section of the class. Hence, there's a good chance your code will get fail.
Rather you could just declare the same thing in this way:
class inside {
std::string plants1[3] = {"...", ...}; // these variables are
std::string plants2[3] = {"...", ...}; // only visible inside the
std::string plants3[3] = {"...", ...}; // class member functions
.
.
}
And after that, you'll get the line executed successfully.

Related

What is the problem I am having with using arrays with classes?

I have been working on a project for my computer science class and have encountered an issue with the code working. I am shown no error except when I try to compile and I get an error that reads:
Exception thrown: write access violation.
_Left was 0xCCCCCCCC.
The purpose of my project is to take a list of names from an external file, read them into an array, sort said array and then output the sorted list all while using a class for the code.
Here is a copy of my code and I would like to extend my gratitude to whoever can help me through my issue:
**Header File**
#include <iostream>
using namespace std;
class person
{
public:
person();
bool get(ifstream&);
void put(ofstream&);
private:
int capacity = 0;
string first_name[CAPACITY];
string last_name[CAPACITY];
int age[CAPACITY];
};```
**Header function definitions cpp file**
#include<iostream>
#include<string>
#include<fstream>
#include<cstdlib>
const int CAPACITY=20;
using namespace std;
#include "Person.h"
//Names constructor
//Postcondition both first name and last name initialized to zero
person::person()
{
first_name[CAPACITY] = "";
last_name[CAPACITY] = "";
age[CAPACITY]=0;
}
bool person::get(ifstream& in)
{
in >> first_name[CAPACITY] >> last_name[CAPACITY] >> age[CAPACITY];
return(in.good());
}
void person::put(ofstream &out)
{
out << first_name[CAPACITY] << last_name[CAPACITY] << age[CAPACITY];
}
**cpp file which holds main**
#include<iostream>
#include<cstdlib>
#include<fstream>
#include<string>
const int CAPACITY = 20;
using namespace std;
#include "Person.h"
void pop(string *xp, string *yp);
void sort(string name[CAPACITY], int count);
int main()
{
class person names[CAPACITY];
ifstream infile;
ofstream outfile;
string filename;
string name[CAPACITY];
int n = 0;
cout << "Enter the file name you wish to open" << endl;
cin >> filename;
infile.open(filename + ".txt");
outfile.open("Person_New.txt");
if (infile.fail())
{
cout << "The file requested did not open" << endl;
exit(1);
}
while (!infile.eof())
{
names[n].get(infile);
n++;
}
sort(name, CAPACITY);
for (int i = 0; i < CAPACITY; i++)
{
names[i].put(outfile);
}
cout << "The file has been created" << endl;
infile.close();
}
void pop(string *xp, string *yp)
{
string temp = *xp;
*xp = *yp;
*yp = temp;
}
void sort(string name[CAPACITY], int count)
{
int i, j;
for (i = 0; i < count - 1; i++)
{
for (j = 0; j < count - i - 1; j++)
{
if (name[j] > name[j + 1])
{
pop(&name[j], &name[j + 1]);
}
}
}
}
Once again Thank you for any support
It sounds to me like the compiler is getting upset that you are trying to write (i.e. assign a value) at an address that you do not have permission to access. I believe your constructor for the class person might be at fault because of how this class stores its variables, as well as the class header:
Constructor for the class person:
`person::person(){
first_name[CAPACITY] = "";
last_name[CAPACITY] = "";
age[CAPACITY] = 0;
}`
Class header for the class person:
`class person{
public:
//stuff
private:
int capacity = 0;
std::string first_name[CAPACITY];
std::string last_name[CAPACITY];
int age[CAPACITY];
//more stuff
}`
C++ is very specific about its naming conventions, so it makes a distinction between capacity and CAPACITY. Because of this, the variable CAPACITY is not defined within the Person.h file.
Also, because CAPACITY is set to a fixed value in your Person.cpp file, whenever you use first_name[CAPACITY], last_name[CAPACITY], or age[CAPACITY] to assign new values, you are only updating the values at the index equal to CAPACITY unless you update the value of CAPACITY itself. In the code you provided, CAPACITY is equal to 20, so your program attempts to update exclusively index 20 with each method call. This will likely cause issues since the person class only attempts to make its arrays on the runtime stack, with a size of 0 each.
Separately, it seems like you want an array of people, but it appears that you are attempting to use a single person object to store the names and ages of multiple people by making these all arrays. Instead, I would recommend making first_name, last_name, and age not arrays, but rather single variables. Then, you can manipulate an array of type person using your CAPACITY variable. You got pretty close, but you can instead declare it as person myPersonArray[CAPACITY] (no need to mention "class" in front of it -- just be sure that you have #include "Person.h" in your main.cpp file). When you want to update a specific person, you can perform an operation like myPersonArray[updateThisIndexNum].update(newFirstName, newLastName, newAge) or some logical equivalent.
As a final note, I almost always highly recommend against using !infile.eof() to control your while loop when reading any file because eof() only indicates whether you have tried to read past the end of an input file. I would highly recommend checking out this post on Stack Overflow where people far more knowledgeable than I explain exactly why this is usually dangerous and how to avoid it.

Vector Isn't Creating Multiple Class Objects

I have a vector that stores multiple class objects for later access. This way my program can create new objects during runtime. This is done like so:
vector<Person> peopleVector;
peopleVector.push_back(Person(name, age));
for (int i = 0; i < peopleVector.size(); i++) {
cout << peopleVector[i].name << endl;
}
This function should print out each objects "name" every time the code runs (it's a function that runs multiple times). However, when I run this, somehow the vector does not increase in size. If you add cout << peopleVector.size(); to that code, you will find that each time it runs, it gets one (obviously assuming you also have the class code which I have below).
I'm curious why I can't create multiple objects in the class.
Class.h
#pragma once
#include <iostream>
using namespace std;
class Person {
public:
Person(string personName, int personAge);
string name;
int age;
};
Person::Person(string personName, int personAge) {
name = personName;
age = personAge;
}
Main.cpp
#include "Class.h"
#include <random>
int main() {
// Necessary for random numbers
srand(time(0));
string name = names[rand() % 82]; // Array with a lot of names
int age = 4 + (rand() % 95);
}
// Create a new person
void newPerson(string name, int age) {
vector<Person> peopleVector;
peopleVector.push_back(Person(name, age));
for (int i = 0; i < peopleVector.size(); i++) {
cout << peopleVector[i].name << endl;
}
}
Just FYI those #includes might be a little bit off because I took that code out of a large section that had like 15 includes.
You are creating an empty vector each time you call your newPerson() function, and then you add a single person to it.
You then display the contents of that vector. What else can it contain, other than the single person that you added?
Problem
Every time a function runs, all local variables inside the function are re-created in their default state. That means that every time you call newPerson, it just recreates peopleVector.
Solution
There are two solutions:
Have newPerson take a reference to a vector, and add it on to that
make peopleVector static, so that it isn't re-initialized every time
First solution:
// Create a new person; add it to peopleVector
// The function takes a reference to the vector you want to add it to
void newPerson(string name, int age, vector<Person>& peopleVector) {
peopleVector.push_back(Person(name, age));
for (int i = 0; i < peopleVector.size(); i++) {
cout << peopleVector[i].name << endl;
}
}
Second solution: mark peopleVector as static
// create a new person; add it to peopleVector
void newPerson(string name, int age) {
// Marking peopleVector as static prevents it from being re-initialized
static vector<Person> peopleVector;
peopleVector.push_back(Person(name, age));
for (int i = 0; i < peopleVector.size(); i++) {
cout << peopleVector[i].name << endl;
}
}

Segmentation fault with dynamically allocated arrays as members of structure in c++?

I am writing a program using an array of structures to store a name, id number, and an array of test scores for a certain amount of students. Both the array of structures and the array of test scores member need to be dynamically allocated. I've gotten down to the function that allows the user to input test scores for each student, however I am having problems with the cin in the last function (getScores function). When using Linux I get a segmentation fault, so I'm assuming it has something to do with the dynamically allocated tests array that is a member of the structure, I just can't see it. I'm wondering how I can go about debugging it and an explanation of why this is actually occurring so I can avoid it in the future.
//Preprocessor Directives
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
//Structure declaration
struct Students
{
string name; //Student name
int idNum; //Student ID number
double *tests; //Pointer to an array of test scores
};
//Function prototypes
Students *getStudents(int &);
double *getTests(int &);
void getInfo(string &, int &, int);
void getScores(double &, string, int);
//Main program section
int main ()
{
int numStudents = 0;
int numTests = 0;
Students *studentFiles = NULL;
//Call the getStudents function
studentFiles = getStudents(numStudents);
//Call the getTests function
studentFiles->tests = getTests(numTests);
for(int i = 0; i < numStudents; i++)
{
//Call the getInfo function
getInfo(studentFiles[i].name, studentFiles[i].idNum, i+1);
}
for(int i = 0; i < numStudents; i++)
{
for(int j = 0; j < numTests; j++)
{
getScores(studentFiles[i].tests[j], studentFiles[i].name, j);
}
}
delete [] studentFiles;
delete [] studentFiels->tests;
return 0;
}
Students *getStudents(int &numStudents)
{
Students *studentFiles = NULL;
//Prompt the user for the number of students
cout<<"Enter the number of students: ";
cin>>numStudents;
//Dynamically allocate an array of structs, one for each student
studentFiles = new Students[numStudents];
return studentFiles;
}
double *getTests(int &numTests)
{
double *tests = NULL;
//Prompt the user for the number of tests
cout<<"Enter the number of tests: ";
cin>>numTests;
cin.ignore();
//Dynamicall allocate an array of integers, one for each test
tests = new double[numTests];
return tests;
}
void getInfo(string &name, int &idNum, int index)
{
//Prompt for each student's name and id number
cout<<"Enter the name of student #"<<index<<": ";
getline(cin, name);
cout<<"Enter the id number of student #"<<index<<": ";
cin>>idNum;
cin.ignore();
}
void getScores(double &test, string name, int numTest)
{
cout<<name<<endl;
cout<<numTest<<endl;
//Prompt for each test score for each student
cout<<"Enter "<<name<<"'s score for test #"<<numTest+1<<": ";
cin>>test;
}
One error is that you access a member of deleted object studentFiles. Reverse the lines to fix that:
delete [] studentFiles->tests;
delete [] studentFiles;
Ideally, use std::vector<> instead of dynamically allocating and releasing memory manually.
Also note, that the code only initializes Student::tests of the first member of the array, the rest of Student objects have this member uninitialized. The result of expression studentFiles[i].tests[j] is undefined and is likely to cause a crash.
You need to initialize Student::tests member of each Student. And when done, deallocate Student::tests of each Student.

C++ code compiles but doesn't run [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am currently writing a Texas Hold'em code in order to learn more about c++ and gain experience. But I recently ran into a problem in which I have no idea what to do.My code compiles just fine without errors but once I make it run and it arrive at a specific function it just stops working (as in I get an error from CodeBlock saying your program has stopped working). I have tried cutting out parts such as loops in the function to see which specific part is the problem but after a couple of days im still at a stop.
Here is the function and class that I believe is the problem:
class Player{
string name;
int bank=100;
static string cards[53];
static string final_card[2][6];
static string table_cards[5];
public:
void set_name(string a){name=a;}
string print_name(){return name;}
void card_generator();
string set_cards(int c){return cards[c];}
int print_bank(){return bank;}
void set_final_card(int i, int max_i);
void print_cards(){for(int i=0;i<6;i++){cout<<final_card[0][i]<<endl;}}
};
void Player::set_final_card(int i, int max_i){
srand(time(NULL));
int tempV = 17;//create temp cards
string tempCards[tempV];
int randNB[tempV];
int check1 = 0, tmp;
while (check1==0){
for(int g=0; g<tempV;g++){
tempCards[g]=cards[rand()%53];
check1=1;
tmp = g - 1;
for(int o=tmp; o!=0; o--){
if (tempCards[g]==tempCards[o]){
check1=0;
}
}
}
}
int p=0,k;
while(p<6){
k=0;
final_card[0][k]=tempCards[p];
k++;
p++;
}
while(p<12){
k=0;
final_card[1][k]=tempCards[p];
k++;
p++;
}
while(p<17){
k=0;
table_cards[k]=tempCards[p];
k++;
p++;
}
}
Here is the full code in case I am wrong of the source of the problem:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <ctime>
using namespace std;
class Player{
string name;
int bank=100;
static string cards[53];
static string final_card[2][6];
static string table_cards[5];
public:
void set_name(string a){name=a;}
string print_name(){return name;}
void card_generator();
string set_cards(int c){return cards[c];}
int print_bank(){return bank;}
void set_final_card(int i, int max_i);
void print_cards(){for(int i=0;i<6;i++){cout<<final_card[0][i]<<endl;}}
};
string Player::cards[53];
string Player::final_card[2][6];
string Player::table_cards[5];
int main () {
int choice1=0, i, max_i, tempV;
string username;
cout<< "Welcome to Texas Hold'Em!\n1-Play\n2-Quit\n";//menu
while((choice1!=1)&&(choice1!=2)){//Makes sure that user enters correct input```
cin>>choice1;
if ((choice1!=1)&&(choice1!=2)){
cout<<"Invalid Input!\nTry again!\n";
}
}
system ("cls");
if (choice1==2){//End Program
return 0;
}
cout<<"How many players?[2-6]"<<endl;
while((i!=2)&&(i!=3)&&(i!=4)&&(i!=5)&&(i!=6)){//Makes sure that user enters correct input
cin>>i;
if ((i!=2)&&(i!=3)&&(i!=4)&&(i!=5)&&(i!=6)){
cout<<"Invalid Input!\nTry again!\n";
}
}
Player player[i];//creating array of players
player[0].card_generator();
max_i = i;//max_i is nb of players
i--;//since arrays start at 0
system("cls");
player[0].set_final_card(i,max_i);
player[0].print_cards();
if (choice1==1) {//SET NAMES OF ALL PLAYERS
for(i=0; i<max_i; i++){
cout<< "Whats your name?\n";
cin>>username;
player[i].set_name(username);
cout<<"Your name is "<< player[i].print_name()<< " and you have "<< player[i].print_bank()<<"$\n";
tempV=i+1;//used bc arrays start at 0
if(tempV!=max_i){
cout<< "Give PC to player "<< i+2 <<endl;
}
_sleep(3000);
system("cls");
}
}
return 0;
}
void Player::set_final_card(int i, int max_i){
srand(time(NULL));
int tempV = 17;//create temp cards
string tempCards[tempV];
int randNB[tempV];
int check1 = 0, tmp;
while (check1==0){
for(int g=0; g<tempV;g++){
tempCards[g]=cards[rand()%53];
check1=1;
tmp = g - 1;
for(int o=tmp; o!=0; o--){
if (tempCards[g]==tempCards[o]){
check1=0;
}
}
}
}
int p=0,k;
while(p<6){
k=0;
final_card[0][k]=tempCards[p];
k++;
p++;
}
while(p<12){
k=0;
final_card[1][k]=tempCards[p];
k++;
p++;
}
while(p<17){
k=0;
table_cards[k]=tempCards[p];
k++;
p++;
}
}
void Player::card_generator(){
string card_value[13];
card_value[0]="1";
card_value[1]="2";
card_value[2]="3";
card_value[3]="4";
card_value[4]="5";
card_value[5]="6";
card_value[6]="7";
card_value[7]="8";
card_value[8]="9";
card_value[9]="10";
card_value[10]="J";
card_value[11]="Q";
card_value[12]="K";
string card_type[4];
card_type[0]="of hearts";
card_type[1]="of diamonds";
card_type[2]="of clubs";
card_type[3]="of spades";
string card[53];
int x=0;
fill_n(card,53,0);
for (int j=0;j<4;j++){
for (int q=0;q<13;q++){
card[x]=card_value[q]+" "+card_type[j];
cards[x]=card[x];
x++;
}
}
}
If you have any criticism about the code itself even if not directly linked to problem feel free to tell me as I'm doing this to learn :D. Thank you in advance!!
#include <iostream>
#include <string>
#include <stdlib.h>
#include <ctime>
Be consistent in what you do. Including <stdlib.h> and <ctime> looks strange. Either include <cstdlib> and <ctime>, or include <stdlib.h> and <time.h>.
using namespace std;
Don't do this. This using imports all names from the std namespace, which is several hundreds. Only import those names that you actually need, or, alternatively, write std::time instead of the unqualified time. This makes it perfectly clear that you are referring to the time from the standard library instead of one that you might have defined yourself.
class Player{
string name;
int bank=100;
static string cards[53];
static string final_card[2][6];
static string table_cards[5];
The cards should not be represented as strings, but as a separate data type called Card, with properties like suit and rank and a to_string method.
public:
void set_name(string a){name=a;}
To make your program fast, pass a as const std::string & instead of a simple string. This will prevent some copying of data. You should give a better name to the parameter, e.g. void set_name(const std::string &name) { this.name = name; }.
string print_name(){return name;}
This method does not print anything, therefore it must not be called print_name.
void card_generator();
Methods usually are named with verbs, not with nouns. So generate_cards would be a better name. But what does generate mean here? (I'm not a native English speaker, but would draw_cards describe it accurately?)
string set_cards(int c){return cards[c];}
A method called set_* usually modifies something. This one doesn't. Why did you name it this way?
int print_bank(){return bank;}
void set_final_card(int i, int max_i);
Give better names to the parameters. From reading only this declaration, I have no idea what i and max_i might mean.
void print_cards(){for(int i=0;i<6;i++){cout<<final_card[0][i]<<endl;}}
};
string Player::cards[53];
string Player::final_card[2][6];
string Player::table_cards[5];
It looks strange that the cards are stored in the Player class, since no poker player should ever have insight to all 52 cards. And why 53? Is there a joker in your game? These three fields should be moved to a class Table. This allows you to have multiple independent tables, which is nice for a big tournament.
int main () {
int choice1=0, i, max_i, tempV;
string username;
cout<< "Welcome to Texas Hold'Em!\n1-Play\n2-Quit\n";//menu
while((choice1!=1)&&(choice1!=2)){//Makes sure that user enters correct input```
Before reading the choice1 variable, you must initialize it. Since you don't do it, you invoke undefined behavior and everything that the program does after that is unpredictable.
cin>>choice1;
if ((choice1!=1)&&(choice1!=2)){
cout<<"Invalid Input!\nTry again!\n";
}
}
system ("cls");
if (choice1==2){//End Program
return 0;
}
cout<<"How many players?[2-6]"<<endl;
while((i!=2)&&(i!=3)&&(i!=4)&&(i!=5)&&(i!=6)){//Makes sure that user enters correct input
Same here. The user hasn't yet entered anything, so how can you check it?
cin>>i;
Add error handling for every input by enclosing it in an if clause: if (std::cin >> i) {.
if ((i!=2)&&(i!=3)&&(i!=4)&&(i!=5)&&(i!=6)){
cout<<"Invalid Input!\nTry again!\n";
}
}
Player player[i];//creating array of players
Don't use arrays, use a std::vector instead. This allows you to easily extend the table to have 10 players. In the end, there should not be a single 6 in your program.
player[0].card_generator();
max_i = i;//max_i is nb of players
Why do you call this variable max_i, when the comment says that max_players would be a better name?
i--;//since arrays start at 0
system("cls");
player[0].set_final_card(i,max_i);
player[0].print_cards();
if (choice1==1) {//SET NAMES OF ALL PLAYERS
for(i=0; i<max_i; i++){
cout<< "Whats your name?\n";
cin>>username;
player[i].set_name(username);
cout<<"Your name is "<< player[i].print_name()<< " and you have "<< player[i].print_bank()<<"$\n";
tempV=i+1;//used bc arrays start at 0
if(tempV!=max_i){
What does the V in tempV mean?
cout<< "Give PC to player "<< i+2 <<endl;
}
_sleep(3000);
system("cls");
}
}
return 0;
}
void Player::set_final_card(int i, int max_i){
srand(time(NULL));
int tempV = 17;//create temp cards
This 17 is a magic number. It would be better to write it as 5 + 6 * 2, since that makes it much clearer.
string tempCards[tempV];
int randNB[tempV];
int check1 = 0, tmp;
while (check1==0){
for(int g=0; g<tempV;g++){
tempCards[g]=cards[rand()%53];
The 53 is wrong here. I can only be wrong. When you select from 52 cards with equal probability, it must be % 52.
check1=1;
tmp = g - 1;
for(int o=tmp; o!=0; o--){
if (tempCards[g]==tempCards[o]){
check1=0;
}
}
}
}
Captain Giraffe has answered this question in the comments. If any newbies like me face a similar problem look up what a debugger is, as errors like these are called run-time errors. Check this page for a simple explanation: http://www.cplusplus.com/forum/articles/28767/ .

A few questions regarding overloading stream operators in c++

I am working on a hangman program and I want to output a status report to the user after each guess. As I am using classes, I need to use a 'friend' keyword. I'm ok with the concept of classes and friends however I am struggling to implement it properly in my program.
The main issue is that the numbers of vowels is not being counted and the number of letters the user can try is not updating. The full alphabet is being displayed each time.
The code of my program is substantial and I'm not going to post all of it here. The issues I have are with the functions remainingLetters(); and vowelCount(). I have attached the relevant code snippets. This code will obviously not compile. I'm just hoping that someone might see an obvious mistake that I've missed.
**Hangman.h:**
{
public:
...
int vowelCount()const; //to be implemented
char* remainingLetters()const;//to be implemented
friend ostream& operator<< (ostream &out, Hangman &game);
private:
...
int vowel_count;
char secretWord[MAXWORDLENGTH];
char* remaining_letters;
}
**hangman.cpp:**
{
...
int Hangman::vowelCount()const
{
int vowel_count = 0;
int i;
secretWord[i];
for(i=0; i<strlen(secretWord); i++)
{
if(secretWord[i]=='a'||secretWord[i]=='e'||secretWord[i]=='i'||secretWord[i]=='o'||secretWord[i]=='u')
{
vowel_count++;
}
}
return vowel_count;
}
char* Hangman::remainingLetters()const
{
char alphabet[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
char *remaining_letters=new char[ALPHABETSIZE];
for(int i=0; i<strlen(secretWord); i++)
{
for(int j=0; j<ALPHABETSIZE; j++)
{
if(secretWord[i]!=alphabet[j])
{
remaining_letters[j]=alphabet[j];
}
}
}
return remaining_letters;
}
ostream& operator<< (ostream &out, Hangman &game)
{
out << "Number of guesses remaining is: " << game.numGuessesAllowed-game.numWrongGuesses << endl
<< "Number of incorrect guesses so far is: "<<game.numWrongGuesses <<endl
<< "Letters remaining are: "<<game.remaining_letters <<endl
<< "Hint: The secret word contains "<<game.vowel_count <<" vowels"<<endl;
return out;
}
}
**main.cpp**
{
...
cout << game;
...
return 0;
}
You need to call the functions vowelCount() and remainingLetters() for the corresponding variables to be calculated (so that you can output them).
Also, char *remaining_letters=new char[ALPHABETSIZE]; will allocate the memory for the letters and initialize each position with 0 -- which also happens to be the string terminating value. So if the first position (letter 'a') is not set, out<<game.remaining_letters will not output anything
Moreover, the function vowelCount() defines the local variable vowel_count that hides the one in the class (member variable), so the member variable will not get updated (uless you explicitly assign the return value of vowelCount() to that member variable) I suggest you delete the local variable declaration from the vowelCount() function and it will use the member variable, which is what you need
The previous paragraph also applies to the member variable remaining_letters
One more thing: the memory allocated with new is not deallocated automatically, and once you return from the function call, the allocated memory is lost (as in there is no way to access it again, but it still uses memory), unless you assign it when the function returns. You will need to pari each new[] call with its corresponding delete[] call. Better yet: allocate the memory in the constructor of the class and delete it in the destructor for the member variable
Note: yet another bug is in this logic:
for(int i=0; i<strlen(secretWord); i++)
{
for(int j=0; j<ALPHABETSIZE; j++)
{
if(secretWord[i]!=alphabet[j])
{
remaining_letters[j]=alphabet[j];
}
}
}
you cycle through the alphabet and every time the current letter in secret word is not matvching, you assign to remaining_letters. This will assignment will happen every time as there will be a letter in the alphabet that does not match the curent secretWord letter.
To fix this, you will need do something like this (note the inversion of the loops):
int secret_len = strlen(secretWord); // cache length, so we don't recalculate it
// every time: secretWord does not change
for(int j=0; j<ALPHABETSIZE; j++)
{
bool found = false; // assume the current ABC letter is not in secretWord
for(int i=0; i<secret_len; i++)
{
if(secretWord[i]!=alphabet[j])
{
found = true; // but it was
}
}
if (!found) // if it wasn't
{
remaining_letters[j]=alphabet[j];
}
}
Your main problem is that you do not keep the vowels count in the class member vowel_count. You store it in a local variable vowel_count and return it but the class member is never updated.