Disagreement between functions,C++

Hi, everyone.
I'm trying to write the code for a hangman game(I already looked though several threads trying to solve my problem).
Basically, the program is supposed to read a .txt file of possible hangman words. It randomly selects a word from the file, hides it behind dashes, and asks the user to guess the word before the poor stick figure gets hanged.

All was going fine and dandy until I had to code the boolean function to check the user's character guess against the random string selected by the program. I run the program, then it throws a warning at me saying "Access violation reading location 0x00000005." after I enter a guess. How do I get rid of this access violation?

Here is the relevant code:
(Definition of bool function starts at line 34,main at line 50.makeGuess() is called at line 80.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <ctype.h>
using namespace std;
string readFile ()//readFile function picks a capital name from the file
{
srand((unsigned)time(0));
int randomcapital=rand()%256+1;
string name;
ifstream capitals;
capitals.open("capitals.txt");
for(int i=0;i<randomcapital;i++)//grabs the name of the capital
{
getline(capitals, name);
}//from here on out in this function, name.length() will provide the length of the name of the capital.
cout << name << endl;//remember to delete this cout statement at the end.using this line to check and make sure the name propertly converts to '-'
for(int j = 0; j< name.length(); j++)//this for loop goes through the capital name and searches for spaces and commas. It then goes on to reveal the spaces and commas so that the user only has to guess for actual letters
{
	if(name[j] != ',' && name[j] != ' ')
		cout << '-';
	if(name[j] == ',')//reffers to a single character in the sting
		cout << ",";
	if(name[j] == ' ')
		cout << " ";
}
return name;
}

//this following function is supposed to take in the name of the capital(curCap) and the current guess(guess) that the user made for the game. 
//It then goes on to check if the guess character is present in curCap.
//If guess is in curCap, then it reveals the letter. If it is not, then it outputs '-'
bool makeGuess (string curCap, char &guess)
{
		for (int k = 0; k< curCap.length(); k++)
		{
			if(curCap[k] != guess)
				{
					return false;
				}
			if(curCap[k] == guess)
				{
					return true;
				}
		}

}

int main (string name)//pass in the name of the capital in question
{
	char guess;
	string temp;
	
	int i = 6;//this is set to 6 to test printing out the gallows.
	newTree(i);//maybe set up the counter in main so that the int can be passed into newTree via main.(since newTree is being called in main)
	cout<<"The place is: ";
	string curCap = readFile();//this prints out the '-' instead of the actual name!

	cout<<"Make a guess. ";//promt user to guess a letter
		do
		{
		cout<<"Please enter a letter from a to z: ";
		cin>> guess;
		}

		while(ispunct(guess) || isdigit(guess));//the do-while loop makes sure the user has entered an alphabet character
		for(i=0; i <name.length();i++)//this is where name is being used

	makeGuess(curCap,guess);
		{
			if(false)
			{
				cout<<'-';
			}
			if(true)
			{
				cout<<guess;
			}
			makeGuess(curCap,guess);
		}
	//after the makeGuess(), we need to update the player board. the makeGuess function returns bool, so, if true, then update the player board to show the guess letter. if false, update the gallows with a new bodypart 


Sorry if it is too lengthy. I tried cutting the code down to what I think is the relevant material.
Several things are wrong:

1.) What is newTree (line 56)?

2.) The control structure on line 72 will never execute, whereas the one on line 76 will always execute.

3.) The make guess function doesn't make sense. The function will exit and return false prematurely if curCap[0] isn't equal to guess.

As to why you're getting the run-time error, I'm not sure. Fix these simple things first and see where that takes you.
Last edited on
1. Sorry, newTree is the function to print out the gallows.I forgot to exclude it from my post. My entire code is at the end of this comment.

3.I modified the makeGuess definition(line117). I thought the for loop in makeGuess would take care of that. How am I supposed to make it look at every single character in the string if the for loop doesn't do so?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <ctype.h>

using namespace std;


string readFile ()//readFile function picks a capital name from the file
{
srand((unsigned)time(0));
int randomcapital=rand()%256+1;
string name;
ifstream capitals;
capitals.open("capitals.txt");
for(int i=0;i<randomcapital;i++)//grabs the name of the capital
{
getline(capitals, name);
}//from here on out in this function, name.length() will provide the length of the name of the capital.
for(int j = 0; j< name.length(); j++)//this for loop goes through the capital name and searches for spaces and commas. It then goes on to reveal the spaces and commas so that the user only has to guess for actual letters
{
	if(name[j] != ',' && name[j] != ' ')
		cout << '-';
	if(name[j] == ',')//reffers to a single character in the sting
		cout << ",";
	if(name[j] == ' ')
		cout << " ";
}
return name;
}

void newTree(int i)//this function creates the board. needs to become int, not void(actually, the function isn't really returning anything, so i dont think it will be neccessary, just make sure that the int from the counter function is passed in). receives the number from a counter. max is 7.min is 1. the counter will let the program know what body parts to show
{ //begining of setting up board
	const int ROW = 8;
	const int COL = 9;

	char hanger [ROW][COL];

	for (int row = 0; row < ROW; row++)//up to hanger[7][8] is the bare tree. the body ppositions come after wards
		for (int col = 0; col < COL; col++)
		{
			hanger[row][col] = ' ';
			hanger[1][2] = '|';
			hanger[0][3] = '_';
			hanger[1][4] = '|';
			hanger[2][4] = '|';
			hanger[3][4] = '|';
			hanger[5][4] = '|';
			hanger[4][4] = '|';
			hanger[6][4] = '|';
			hanger[7][0] = '-';
			hanger[7][1] = '-';
			hanger[7][2] = '-';
			hanger[7][3] = '-';
			hanger[7][4] = '-';
			hanger[7][5] = '-';
			hanger[7][6] = '-';
			hanger[7][7] = '-';
			hanger[7][8] = '-';
			if(i ==1)
			{
				hanger[2][2] = '*';
			}
			if(i ==2)
			{
				hanger[2][2] = '*';
				hanger[3][2] = '|';
			}
			if(i==3)
			{
				hanger[2][2] = '*';
				hanger[3][2] = '|';
				hanger[3][1] = '-';
			}
			if (i ==4)
			{
				hanger[2][2] = '*';
				hanger[3][2] = '|';
				hanger[3][1] = '-';
				hanger[3][3] = '-';
			}
			if(i ==5)
			{
				hanger[2][2] = '*';
				hanger[3][2] = '|';
				hanger[3][1] = '-';
				hanger[3][3] = '-';
				hanger[4][1] = '/';
			}
			if(i ==6)
			{
				hanger[2][2] = '*';
				hanger[3][2] = '|';
				hanger[3][1] = '-';
				hanger[3][3] = '-';
				hanger[4][1] = '/';
				hanger[4][3] = '\\';
			}

		}//end of setting up a board

		for (int r = 0; r <8; r++)
		{
		for (int c = 0; c < 9; c++)
		cout << hanger[r][c];
		cout << endl;
		}
}

//this following function is supposed to take in the name of the capital(curCap) and the current guess(guess) that the user made for the game. 
//It then goes on to check if the guess character is present in curCap.
//If guess is in curCap, then it reveals the letter. If it is not, then it outputs '-'
bool makeGuess (string curCap, char &guess)
{
	for (int k = 0; k< curCap.length(); k++)
	{
		if(curCap[k] == guess)
			{
				return true;
			}
		else
			return false;
	}

}

int main (string name)//pass in the name of the capital in question
{
	char guess;
	string temp;
	
	int i = 6;//this is set to 6 to test printing out the gallows.
	newTree(i);//maybe set up the counter in main so that the int can be passed into newTree via main.(since newTree is being called in main)
	cout<<"The place is: ";
	string curCap = readFile();//this prints out the '-' instead of the actual name!

	cout<<"Make a guess. ";//promt user to guess a letter
		do
		{
		cout<<"Please enter a letter from a to z: ";
		cin>> guess;
		}

		while(ispunct(guess) || isdigit(guess));//the do-while loop makes sure the user has entered an alphabet character
		for(i=0; i <name.length();i++)//this is where name is being used

	makeGuess(curCap,guess);
		
			if(false)
			{
				cout<<'-';
			}
			if(true)
			{
				cout<<guess;
			}	
		
	//after the makeGuess(), we need to update the player board. the makeGuess function returns bool, so, if true, then update the player board to show the guess letter. if false, update the gallows with a new bodypart

	system("pause");
}







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
for (int row = 0; row < ROW; row++)//up to hanger[7][8] is the bare tree. the body ppositions come after wards
		for (int col = 0; col < COL; col++)
		{
			hanger[row][col] = ' ';
			hanger[1][2] = '|';
			hanger[0][3] = '_';
			hanger[1][4] = '|';
			hanger[2][4] = '|';
			hanger[3][4] = '|';
			hanger[5][4] = '|';
			hanger[4][4] = '|';
			hanger[6][4] = '|';
			hanger[7][0] = '-';
			hanger[7][1] = '-';
			hanger[7][2] = '-';
			hanger[7][3] = '-';
			hanger[7][4] = '-';
			hanger[7][5] = '-';
			hanger[7][6] = '-';
			hanger[7][7] = '-';
			hanger[7][8] = '-';
			if(i ==1)
			{
				hanger[2][2] = '*';
			}
			if(i ==2)
			{
				hanger[2][2] = '*';
				hanger[3][2] = '|';
			}
			if(i==3)
			{
				hanger[2][2] = '*';
				hanger[3][2] = '|';
				hanger[3][1] = '-';
			}
			if (i ==4)
			{
				hanger[2][2] = '*';
				hanger[3][2] = '|';
				hanger[3][1] = '-';
				hanger[3][3] = '-';
			}
			if(i ==5)
			{
				hanger[2][2] = '*';
				hanger[3][2] = '|';
				hanger[3][1] = '-';
				hanger[3][3] = '-';
				hanger[4][1] = '/';
			}
			if(i ==6)
			{
				hanger[2][2] = '*';
				hanger[3][2] = '|';
				hanger[3][1] = '-';
				hanger[3][3] = '-';
				hanger[4][1] = '/';
				hanger[4][3] = '\\';
			}

		}//end of setting up a board 


Why is all of this inside the loops?
This section sets up the hanging man and the gallows he will hang from.
Lines 4-21 set up the empty gallows(it will show up regardless of which if statement is called to).
Each of the if statements provide the body parts based on how many mistakes the user makes:
if the user makes one mistake, his head gets drawn on the gallows.
if the user makes another mistake, the torso gets drawn on the gallows.
and that goes on until the user makes six mistakes. Once you get to that point, your guy is a goner.

I plan on setting up a counter to keep track of how many mistake the user makes. For now, I set i=6 in line 133 so I could concentrate on my current Boolean problem.
I mean why are you doing each part 56 times when 90% of it you only need to do once. Only line 4 (43 in yours) should be inside the loop.
If only line 4 is in the loop, then wouldn't it leave every spot as a blank?

Do you mean something like this?:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
for (int row = 0; row < ROW; row++)//up to hanger[7][8] is the bare tree. the body ppositions come after wards
		for (int col = 0; col < COL; col++)
		{
			hanger[row][col] = ' ';
			hanger[1][2] = '|';
			hanger[0][3] = '_';
			hanger[1][4] = '|';
			hanger[2][4] = '|';
			hanger[3][4] = '|';
			hanger[5][4] = '|';
			hanger[4][4] = '|';
			hanger[6][4] = '|';
			hanger[7][0] = '-';
			hanger[7][1] = '-';
			hanger[7][2] = '-';
			hanger[7][3] = '-';
			hanger[7][4] = '-';
			hanger[7][5] = '-';
			hanger[7][6] = '-';
			hanger[7][7] = '-';
			hanger[7][8] = '-';
			if(i >=1 )
				hanger[2][2] = '*';
			if(i >=2)
				hanger[3][2] = '|';
			if(i>=3)
				hanger[3][1] = '-';
			if (i >=4)
			
				hanger[3][3] = '-';
			if(i >=5)
				hanger[4][1] = '/';
			if(i ==6)
				hanger[4][3] = '\\';
			

		}//end of setting up a board  
No because you write over the spots after the loop. What I mean is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
for (int row = 0; row < ROW; row++)//up to hanger[7][8] is the bare tree. the body ppositions come after wards
		for (int col = 0; col < COL; col++)
                {
			hanger[row][col] = ' ';
		        if(i >=1 )
			        hanger[2][2] = '*';
		        if(i >=2)
			        hanger[3][2] = '|';
		        if(i>=3)
			        hanger[3][1] = '-';
		        if (i >=4)
			        hanger[3][3] = '-';
		        if(i >=5)
			        hanger[4][1] = '/';
		        if(i ==6)
			        hanger[4][3] = '\\'; 
                }
		hanger[1][2] = '|';
		hanger[0][3] = '_';
		hanger[1][4] = '|';
		hanger[2][4] = '|';
		hanger[3][4] = '|';
		hanger[5][4] = '|';
		hanger[4][4] = '|';
		hanger[6][4] = '|';
		hanger[7][0] = '-';
		hanger[7][1] = '-';
		hanger[7][2] = '-';
		hanger[7][3] = '-';
		hanger[7][4] = '-';
		hanger[7][5] = '-';
		hanger[7][6] = '-';
		hanger[7][7] = '-';
		hanger[7][8] = '-';

Possibly doing the loop after the other assignments. Though half of those could be shorted with smaller loops.
Last edited on
Oh I see. Thanks!
Now I just have the Boolean problem to worry about.
It's very simple actually, you can do something to this effect:

1
2
3
4
5
6
7
8
9
bool makeGuess(std::string curCap, char& guess) {
	bool flag = false;//the function assumes that the guess isn't in curCap until it finds a match
	for(unsigned short i=0; i<curCap.size() && flag == false; ++i) {
		if(curCap[i]==guess) {
			flag = true;
		}
	}
	return flag;
}
I was able to get rid of the build errors, but it still tells me I have an access violation: "Unhandled exception at 0x6431CCC8 (msvcp110d.dll) in prjct4.exe: 0xC0000005: Access violation reading location 0x00000005."

I modified the bool function definition(line 88) and how it is called in main(line 125).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <ctype.h>

using namespace std;


string readFile ()//readFile function picks a capital name from the file
{
srand((unsigned)time(0));
int randomcapital=rand()%256+1;
string name;
ifstream capitals;
capitals.open("capitals.txt");
for(int i=0;i<randomcapital;i++)//grabs the name of the capital
{
getline(capitals, name);
}//from here on out in this function, name.lengthparenthesis will provide the length of the name of the capital.
int nameLength = name.length();
for(int j = 0; j < nameLength; j++)//this for loop goes through the capital name and searches for spaces and commas. It then goes on to reveal the spaces and commas so that the user only has to guess for actual letters
{
	if(name[j] != ',' && name[j] != ' ')
		cout << '-';
	if(name[j] == ',')//reffers to a single character in the string
		cout << ",";
	if(name[j] == ' ')
		cout << " ";
}
return name;
}

void newTree(int i)//this function creates the board. needs to become int, not void(actually, the function isn't really returning anything, so i dont think it will be neccessary, just make sure that the int from the counter function is passed in). receives the number from a counter. max is 7.min is 1. the counter will let the program know what body parts to show
{ //begining of setting up board
	const int ROW = 8;
	const int COL = 9;

	char hanger [ROW][COL];

	for (int row = 0; row < ROW; row++)//hanger [1][2] to hanger[7][8] is the bare tree. the body ppositions come after wards
		for (int col = 0; col < COL; col++)
			{
		hanger[row][col] = ' ';
			if(i >=1 )
				hanger[2][2] = '*';
			if(i >=2)
				hanger[3][2] = '|';
			if(i>=3)
				hanger[3][1] = '-';
			if (i >=4)
				hanger[3][3] = '-';
			if(i >=5)
				hanger[4][1] = '/';
			if(i ==6)
				hanger[4][3] = '\\'; 
			}
				hanger[1][2] = '|';
				hanger[0][3] = '_';
				hanger[1][4] = '|';
				hanger[2][4] = '|';
				hanger[3][4] = '|';
				hanger[5][4] = '|';
				hanger[4][4] = '|';
				hanger[6][4] = '|';
				hanger[7][0] = '-';
				hanger[7][1] = '-';
				hanger[7][2] = '-';
				hanger[7][3] = '-';
				hanger[7][4] = '-';
				hanger[7][5] = '-';
				hanger[7][6] = '-';
				hanger[7][7] = '-';
				hanger[7][8] = '-';
			//end of setting up a board

		for (int r = 0; r <8; r++)
		{
		for (int c = 0; c < 9; c++)
		cout << hanger[r][c];
		cout << endl;
		}
	}

//this following function is supposed to take in the name of the capital and the current guess that the user made for the game. 
//It then goes on to check if the guess character is present in curCap.
//If guess is in curCap, then it reveals the letter. If it is not, then it outputs '-'
bool makeGuess (string curCap, char &guess)
{
	bool flag = false;
	for (unsigned short i = 0; i< curCap.size() && flag == false; i++)
	{
		if(curCap[i] == guess)
		{
				flag = true;
		}

	}
	return flag;
}

int main (string name)//pass in the name of the capital in question
{
	char guess;
	string temp;
	
	int i = 6;//this is set to 6 to test printing out the gallows.
	newTree(i);//maybe set up the counter in main so that the int can be passed into newTree via main.(since newTree is being called in main)
	cout<<"The place is: ";
	string curCap = readFile();//this prints out the '-' instead of the actual name!

	cout<<"Make a guess. ";//promt user to guess a letter
		do
		{
		cout<<"Please enter a letter from a to z: ";
		cin>> guess;
		}

		while(ispunct(guess) || isdigit(guess));//the do-while loop makes sure the user has entered an alphabet character
		int nameLength = name.length();
		for(int i=0; i <nameLength;i++)
		{
			while (true)
			{
			if(makeGuess(curCap,guess))
			{
			cout<<guess;
			break;
			}
			else
			{
				cout<<'-';
			}
			}
		}
	system("pause");
}
int main (string name)//pass in the name of the capital in question
is invalid (surprisingly it compiles)

int main(int argc, char* argv[])
is the correct form

if you want that a string is passed via command line you need argv[1]:
1
2
3
4
if(argc > 1)
  name = argv[1];
else
  // missing paramter 
I've got it working now. Thank you very much!
Topic archived. No new replies allowed.