problem with a while loop

closed account (9iz0SL3A)
I am writing a code for a hangman game, and I have a problem with getting the computer to write a '_' for every letter in the while loop. (Line 24)

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
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>

using namespace std;

int main() 
{
  string answer;
  string empty_list;
  int i;
  string letter;
  bool found;

  srand(time(0));

  const string wordList[19] = { "sanctuary", "sting", "cabinet", "terrify", "harvest", "departure", "collar", "profession", "muscle", "feeling", "process", "recommend", "deter", "bald", "date", "shadow", "particle", "build", "tired" };

  string word = wordList[rand() % 4];
  
  i = 0;
  empty_list = "h";

  int l = word.length();

  while(l > 0)
   {empty_list[i] = '_';
   i = i + 1;
   l = l - 1;}
  cout << empty_list << endl;

  int count = 0;
  int lives = 7;
  int size = word.size();

  while (count < size && lives > 0)
  ;
   {
    cout << "guess a letter" << endl;
    cin >> letter;

    found = false;
    if (word.find(letter) == std::string::npos) 
    {
      found = true;
      cout << "that letter is correct :O" << endl;
      count = count + 1;
    } 
    else
    {
      cout << "that letter is incorrect :(" << endl;
      lives = lives - 1;
    }
   }
}
empty_list = string(word.length(), '_'); will fill empty_list with word.length() number of _'s.

Note that the semi-colon on line 38 is causing the loop on line 37 to be infinite. You should remove it.

empty_list = "h";
What is "h" supposed to mean here?

string word = wordList[rand() % 4];
This will only choose numbers from indices 0 through 3, not all 19 indices.

Example of a way to reveal letters:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Example program
#include <iostream>
#include <string>
using namespace std;

int main()
{
    string word = "apple";
    string blanked_word(word.length(), '_');
    
    char guess = 'p';
    
    for (size_t i = 0; i < word.length(); i++)
    {
        if (word[i] == guess)
        {
            blanked_word[i] = guess;
        }
    }
    
    cout << blanked_word << '\n';
}

_pp__
Last edited on
line 38 disables the while loop. if you did that on purpose to debug, its fine.


if (word.find(letter) == std::string::npos)

this seems wrong to me.
that says:
if letter is not in string
found is true … that letter is correct .. etc
this seems backwards, like you would want != instead

when you DO find it, you need to set the string full of _ at that position to the letter. and you need to do it for all copies of the letter, not just the first, so you need to find() all of the instances. It may be simple to just say
for(I = 0; I < length; I++)
if(word[I] == letter)
{
dashes[I] = letter;
found = true;
}
if found... (manage lives)
you can do it with find() and other utilities but this is the kind of place where generic tools vs tailored loop favor a tailored loop to solve your problem directly.
Last edited on
Hello strawberrycatshake,

If you would set up your code 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
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
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>

using namespace std;

int main()
{
    string answer;
    string empty_list;
    int i;
    string letter;
    bool found;

    //srand(time(0));
    srand(static_cast<unsigned int>(time(nullptr)));

    const string wordList[19] =
    {
        "sanctuary",
        "sting",
        "cabinet",
        "terrify",
        "harvest",
        "departure",
        "collar",
        "profession",
        "muscle",
        "feeling",
        "process",
        "recommend",
        "deter",
        "bald",
        "date",
        "shadow",
        "particle",
        "build",
        "tired"
    };

    string word = wordList[rand() % 4];

    i = 0;
    empty_list = "h";

    int l = word.length();

    while (l > 0)
    {
        empty_list[i] = '_';
        i = i + 1;
        l = l - 1;
    }

    cout << empty_list << endl;

    int count = 0;
    int lives = 7;
    int size = word.size();

    while (count < size && lives > 0)
        ;
    {
        cout << "guess a letter" << endl;
        cin >> letter;

        found = false;

        if (word.find(letter) == std::string::npos)
        {
            found = true;

            cout << "that letter is correct :O" << endl;

            count = count + 1;  // <--- count++;
        }
        else
        {
            cout << "that letter is incorrect :(" << endl;

            lives = lives - 1;  // <--- lives++;
        }
    }
}

Defining the constant string this way makes it easier to add, delete or change.

Line 17 is a more portable way to write "srand()". This video is worth watching
https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

You should also initialize your variables:
1
2
3
4
5
string answer;
string empty_list;
int i{};
string letter;
bool found{};


In line 49 while (one > zero). See the confusion using the lower case "L". This would always evaluate to true, but you are using the lower case "L" which is set before the while loop.

i = i + 1;. You should use i++; or l--;.

Properly formatted and indented the compiler would see line 63 as being the end , or part of, line 62. Thus making the while loop self contained and an if true it would be an endless loop. What you are actually seeing is that line 63 is indented as an empty statement and only this indented line is part of the while loop.

The block that you are expecting to be part of the while is not. It will never be executed because "count", "size" and lives" never change, so only if the while condition fails would the following be executed.

Andy

Edit: line 17
Last edited on
closed account (9iz0SL3A)
thanks :D
Topic archived. No new replies allowed.