Whites space being read into the rear of string using getline() - c++

Look, i have been writing this guessing game for a day and a half now. I keep getting errors related to using cin and getline together, and using a lot of advice I received from Stackoverflow, I thought I fixed all the bugs. Also, I realize it's best not to use >> and getline together, but to be honest, I don't know any other way, and I am afraid I will lose points if I use features of the language that our professor hasn't specifically taught us. So please just help me out, I have been ocd-ing like a maniac.
The game works correctly, and the game repeats, (I also know that using goto is evil, but this is just a very basic guessing game. I pinky promise not to ever use it in real life)
The problem arises when the game repeats a second time. After the game prompts the user to enter Y to continue, and they do, it will goto the start of my do-while loop, as it should. Stack unwinding be damned.
Next, it will read in the user input, ignoring white space at the stare of cin. But somehow, white space hops in at the end of my word after a few runs? I am baffled by this, as I thought that my loop which tests each index using the isalpha function would prevent this?
I could really use some concrete code to fix this, I have been up all night. Suggestions are fine but I don;t fully understand them and I am not allowed to use a good chunk of this languages features. Yes, I realize that is ridiculous, but I'm not my professor.
Here is a screenshot of the logical error:
Here is my code so far: You can read some of my comments to see the different paths this beast has been down:
#include<iostream>
#include<string>
#include <algorithm>
#include <iostream>
#include <string>
#include <functional>
#include <ctype.h>
using namespace std;
int main() {
string secretWord;
string secretWordClean = "";
string guessedLetters; //to be loaded with _ characters equal to length of secretWord
string incorrectlyGuessedChars = "";
char individualCharGuess;
char playAgain;
size_t countOfLetters = 0; //begine count at 0
size_t guessesRemaining;
int guessedUsed;
begin_game://label which we can use to bring us back to the start of the do-while loop at any time
//do{//start of the game
cout << "Please enter a secret word: ";
std::cin >> std::ws;
getline(std::cin, secretWord);
secretWord.erase(std::remove_if(secretWord.begin(), secretWord.end(), std::not1(std::ptr_fun(isalnum))), secretWord.end());
//std::cout << secretWord << "\n";
for(int i = 0; i < secretWord.length(); i++){
if (isalpha(secretWord[i])){
secretWordClean += secretWord[i];
}
}
secretWord = secretWordClean; //assign all alpha secret word string back to original variable for better readability
guessesRemaining = secretWord.length() * 2;
//cout << "Please enter a secret word: ";
//cin >> secretWord;
do{//start of the guessing portion of game
for(int i = 0; i < secretWord.length(); i++){
guessedLetters += "_"; //fills guessedLetters with blanks equal to the length of the secretWord
}
cout << "Please guess a letter, you have " << guessesRemaining << " guesses remaining!" << endl;
cin >> individualCharGuess;
for(int i = 0; i < secretWord.length(); i++){ //every complete iteration of this for loop = one single guess
if(secretWord[i] == individualCharGuess){
guessedLetters[i] = individualCharGuess; //will replace the spaces with the correct character, if guessed
countOfLetters++; //if any letter is guessed correctly, this indicator will be incrimented above 0
continue;
}
if(secretWord.find(individualCharGuess) == string::npos){
if(incorrectlyGuessedChars.find(individualCharGuess) == string::npos){
incorrectlyGuessedChars += individualCharGuess;
}
}
}
if(secretWord.compare(guessedLetters) == 0){
cout << "You win! The word was: " << secretWord << endl;
guessedUsed = ((secretWord.length() * 2) - guessesRemaining) + 1 ;
cout << "You used " << guessedUsed << " guesses." << endl;
cout << "Play again? Enter Y for Yes, or anything else to exit: ";
cin >> playAgain;
if(playAgain != 'Y'){
break; //exit the loop if user guesses all the letters and doesn't want to play again
}
else {
incorrectlyGuessedChars = "";
secretWordClean = "";
//continue;
goto begin_game;
}
}
guessesRemaining--; //we decriment our total guesses remaining if the user does not win the game or run out of guesses
if(countOfLetters > 0){
cout << "You have correctly guessed a letter!" << endl;
cout << "Here are the letters you have guessed correctly so far: ";
cout << guessedLetters << endl;
cout << "Here are the letters you have guessed incorrectly so far: ";
cout << incorrectlyGuessedChars << endl;
countOfLetters = 0; //reset the counter to prepare for next iteration of do-while loop
}
else if (guessesRemaining <= 0) {
cout << "You have run out of guesses!" << endl;
cout << "Here are the letters that you guessed correctly: ";
cout << guessedLetters << endl;
cout << "Here are the letters you guessed incorrectly: ";
cout << incorrectlyGuessedChars << endl;
cout << "The secret word was: " << secretWord << endl;
cout << "Play again? Enter Y for Yes, or anything else to exit: ";
cin >> playAgain;
if(playAgain != 'Y'){
break; //exit the loop if user guesses all the letters and doesn't want to play again
}
else {
secretWordClean = "";
incorrectlyGuessedChars = "";
//continue;
goto begin_game;
}
}
else {
cout << "You guessed wrong! Keep trying, " << guessesRemaining << " guesses to go!" << endl;
cout << "Here are the letters you have guessed correctly so far: ";
cout << guessedLetters << endl;
cout << "Here are the letters you have guessed incorrectly so far: ";
cout << incorrectlyGuessedChars << endl;
}
}while (secretWord.compare(guessedLetters) != 0 || guessesRemaining != 0); //use to repeat the request for a single char guess
return 0;
}

You should initialize with blanks (the _ character) the string before the loop starts, not at the beginning of every iteration, change your code to:
for (int i = 0; i < secretWord.length(); i++) {
guessedLetters += "_"; //fills guessedLetters with blanks equal to the length of the secretWord
}
do{ //start of the guessing portion of game
... rest of the code ...
if you don't, at every iteration of your game the guessedLetters variable is going to have more _ characters appended at the end of it, spoiling your final string comparison.
You should also clear the guessedLetters if you plan to play again:
else {
incorrectlyGuessedChars = "";
secretWordClean = "";
guessedLetters = ""; // Cleanup
//continue;
goto begin_game;
}
as a sidenote: gotos are a terrible programming practice and can render the code very unreadable/unmaintainable. I suggest redesigning your application without using gotos in a future revision.

Related

Check letters against the word of an arbitrary size in a Hangman game

Currently I am working on a hangman game, I had previously coded it to only work for a 5 letter word, but now would like to make it handle any length of word, how could I change this code to make it work how I want it to?
#include "stdafx.h"
#include <iostream>
#include <string>
#include <stdlib.h>
#include <cstdlib>
using namespace std;
int main()
{
string word;
int tries;
string guess;
string wordguess;
string output;
cout << "Enter a word for player two to guess: ";
cin >> word;
system("CLS");
cout.flush();
cout << "Guess the word!" << endl;
for (int i = 0; i < word.length(); i++)
{
cout << "_ ";
}
cout << "Enter a letter: ";
cin >> guess;
for (int tries = 5; tries > 0; tries--)
{
if (guess[0] == word[0]) {
output[0] = word[0];
cout << "You guessed the first letter! Good job!" << endl;
}
if (guess[0] == word[1]) {
output[2] = word[1];
cout << "You guessed the second letter! Good job!" << endl;
}
if (guess[0] == word[2]) {
output[4] = word[2];
cout << "You guessed the third letter! Good job!" << endl;
}
if (guess[0] == word[3]) {
output[6] = word[3];
cout << "You guessed the fourth letter! Good job!" << endl;
}
if (guess[0] == word[4]) {
output[8] = word[4];
cout << "You guessed the fifth letter! Good job!" << endl;
}
cout << output << endl;
cout << "You have " << tries << " tries left. Take a guess at the word: " << endl;
cin >> wordguess;
if (wordguess == word)
{
cout << "Congratulations, you guessed the word correctly!" << endl;
break;
}
}
system("pause");
return 0;
}
As you can tell I was checking each position from 0 to 4 (first through fifth letter). I know there are plenty of ways that I could have coded this better but as you can guess, I am new to coding and this is the way I thought of it. Please note this is still a work in progress so it is not fully complete. Any help would be great!
When designing an algorithm, think of how you would do this by hand, without a computer. Then let the code do the same.
If you were checking your friend's guess against a word written on sand, you would probably go about it like this:
go through the written pattern character by character, pronouncing your word in memory
for each letter, check if it is equal to the guess
if it is
replace the placeholder with it
memorize that your friend guessed right.
Also note if there are any placeholders left
if there aren't, your friend wins
finally, if your friend didn't guess right, score them a penalty point and check if they lose
Now, all that leaves is to put this down in C++. The language provides all sorts of entities - let's check which ones fit ours needs the best:
the word and the current pattern - strings of a fixed size
bits to memorize:
whether the current guess is right - bool
placeholders left - int
penalty points (or, equivalently, attempts left) - int
parts of the algorithm:
looping over a string - for loop of one of a few kinds
we need to replace the character in the pattern at the same index as the guessed letter in the word. So, we need to have the index when looping. Thus the flavor with the index variable, for(std::string::size_type i = 0; i < str.size(); ++i) probably fits the best.
// Example program
#include <iostream>
#include <string>
using namespace std;
class my_game
{
private:
string congrats_array[15] = {"first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "nineth", "tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth"};
string word_to_guess;
int tries_left;
int word_length;
int letters_guessed_count;
string guessed_letters;
void check_letter(char letter);
void print_current_word_state();
public:
my_game();
void begin_the_game();
void play_the_game();
};
my_game::my_game()
{
}
void my_game::begin_the_game()
{
cout << "Enter a word for player to guess: " << endl;
cin >> word_to_guess;
system("CLS");
cout.flush();
cout << "Enter the tries amount!\n" << endl;
cin >> tries_left;
word_length = word_to_guess.size();
guessed_letters = "_";
letters_guessed_count = 0;
for(int i = 0; i < word_length - 1; i++){
guessed_letters += "_";
}
}
void my_game::play_the_game()
{
cout << "Guess the word!" << endl;
char letter;
for(int i = 0; i < tries_left; i++)
{
cout << guessed_letters << endl;
cout << "Enter a letter: " << endl;
cin >> letter;
check_letter(letter);
if(letters_guessed_count == word_length){
cout << "Congrats! You won!" << endl;
return;
}
}
cout << "You lose" << endl;
}
void my_game::check_letter(char letter)
{
for(int i = 0; i < word_length; i++)
{
if(word_to_guess[i] == letter && guessed_letters[i] != letter)
{
guessed_letters[i] = letter;
letters_guessed_count++;
cout << "You guessed the" << congrats_array[i] <<"letter! Good job!" << endl;
}
}
}
int main()
{
my_game game;
game.begin_the_game();
game.play_the_game();
}
So, in short what you need to do this with words of any arbitrary length is to use string's .substr() function and the stringstream library's .str() and << and >> operators. This version of your code uses a function that inserts a correctly guessed character at the appropriate indexed location. This will gradually replace the "_________" with letters at the correct places. This is much easier to do in Java, but stringstream is a good library I would highly recommend getting familiar with it. I'll leave the problem of how to handle multiple instances of a guessed character up to you (ie 'i' in "bibliography")
#include <string>
using std::string;
#include <sstream>
using std::stringstream;
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
string newString(string, int, string);
int main()
{
string word;
string guess;
int tries;
string output;
string input;
cout << "Enter word for player 2 to guess: ";
cin >> word;
stringstream ss;
//---------- fills the stream with "_"s matching the length of word
for(int i = 0; i < word.length(); i++)
ss << "_";
//----------- assigns the initial value of "___..." to output
ss >> output;
//----------- sets up the loop
tries = 5;
bool found = false;
for(int i = 0; i < 5; i++)
{
cout << "\nTry " << i << " of 5: Enter a letter or guess the word: ";
cin >> input;
if(input == word)
{
cout << "Congratulations, you guessed the word correctly!" << endl;
break;
}
//------------------ else, proceed with replacing letters
if(word.find(input) != std::string::npos)
{
size_t position = word.find(input); // finds index of first instance of the guessed letter
cout << "You guessed the " << position+1 << " letter! Good job!" << endl; // since strings start at index 0, position+1
//------- replaces appropriate "_" with the guessed letter
output = newString(input, position, output);
cout << "\n" << output;
// Around here you'll want to set up a way to deal with multiple instances
// of the same letter
}
else
cout << "Incorrect guess" << endl;
}
return 0;
}
//---------------------------------------------------
string newString(string guess, int index, string word)
{
string NewString;
stringstream temp;
//---------- hack up the string into sections before and after the index
string before = word.substr(0, index);
string after = word.substr(index+1, word.length() - index+1);
//---------------- populates the new stringstream and assigns it to the result
temp << before << guess << after;
NewString = temp.str();
return NewString;
}

Conditional cin giving stacked cout messages

Using C++ (g++-4.7 on Mint 16).
Code is a unrefined (and unfinished) Tic-Tac-Toe game.
#include <iostream>
using namespace std;
int main()
{
//initial data
char turn='A';
char ttt[] = {'1','2','3','4','5','6','7','8','9'};
int move;
int over=0; //0 is no, 1 is yes
int valid=0;
while ( over == 0)
{
//display
cout << "\n" << ttt[0] << "|" << ttt[1] << "|" << ttt[2] <<"\n-----\n";
cout << ttt[3] << "|" << ttt[4] << "|" << ttt[5] <<"\n-----\n";
cout << ttt[6] << "|" << ttt[7] << "|" << ttt[8] <<"\n\n Choose a number (Player " << turn << "):";
//ask enter for play with turn
cin >> move;
cout << "\n";
valid = 0;
while (valid == 0)
{
//check if input is valid
if (((move > 0) and (move < 10)) and
((ttt[move-1] != 'A') and (ttt[move-1] != 'B')) and
(cin))
{
ttt[move-1] = turn;
valid=1;
}
else
{
cout << "Invalid slot. Choose a number (Player " << turn << "):";
cin >> move;
cout << "\n";
}
}
//check if done if no //change turn then goto //display
if (((ttt[0]==ttt[1]) and (ttt[1]==ttt[2])) or
((ttt[3]==ttt[4]) and (ttt[4]==ttt[5])) or
((ttt[6]==ttt[7]) and (ttt[7]==ttt[8])) or
((ttt[0]==ttt[3]) and (ttt[3]==ttt[6])) or
((ttt[1]==ttt[4]) and (ttt[4]==ttt[7])) or
((ttt[2]==ttt[5]) and (ttt[5]==ttt[8])) or
((ttt[0]==ttt[4]) and (ttt[4]==ttt[8]))or
((ttt[2]==ttt[4]) and (ttt[4]==ttt[6])))
{
//display winner or say draw
cout << "Player " << turn << " wins!\n";
over=1;
}
else
{
//change turn
if (turn=='A')
{ turn='B';
}
else
{ turn='A';
}
}
}
return 0;
}
There seem to be a bug on the code. On the part where check if input is valid the and (cin) seem to be failing.
When entering a character, (Instead of a number) it output continuously stacks of:
Invalid slot. Choose a number (Player A or B):
I tested the rest of condition without it, it was all working well. Is there a problem on the code or is this really "cin" problem? I've also tried out !(!cin) but it's the same scenario.
You must clear the fail bit from the cin stream in your else block.
When you enter a character that isn't an integer, the cin stream sets the fail bit, which you correctly check for in your if statement, but you never clear it afterward. This causes your input validity check to be false forever.
#include <limits>
...
else
{
cin.clear(); // Add this line
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // And this one
cout << "Invalid slot. Choose a number (Player " << turn << "):";
cin >> move;
cout << "\n";
}
For additional information, see the documentation for std::basic_ios::clear
Update: see this question and this question for similar problems.
Essentially, you also need to tell cin to ignore whatever is in the stream or it will continually set the fail bit with its bad contents you haven't cleared yet. I modified the above snippet to work.

How to keep track of letters already guessed in Hangman game for C++?

This assignment given to me was to copy a Hangman game from our textbook and modify it to specific instructions in the book. I have spent a lot of hours trying to research this issue and find a reason why I keep getting the same error message that I do. Everywhere I have looked, everyone that have attempted to modify this code have attempted with arrays and have had the same luck that I have. I'm currently doing a chapter in Strings and was planning on doing most of my statement that is requested by the instructions in String.
What I need to modify in this code is to:
Keep track of all letters that are input by the user
Send an error message to the user if they input a letter that is already entered
The main issue I am having is that when I compile this code and put in the same letter that I have already put in, it terminates with the message:
terminate called after throwing an instance of 'std::out of range'
what(): basic_string::substr
#include <iostream>
#include <string>
using namespace std;
int main()
{
//declare variables
string origWord = " ";
string letter = " ";
char dashReplaced = 'N';
char gameOver = 'N';
int numIncorrect = 10;
string displayWord = "-----";
string usedLetter = " ";
string letterNotGuessedYet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int letterPlace = 0;
//get original word
do //begin loop
{
cout << "Enter a 5-letter word in uppercase: ";
getline(cin,origWord);
}while(origWord.length() != 5); //end do loop
//clear the screen
system("cls");
//start guessing
cout <<"Guess this word: " << displayWord << endl;
while(gameOver =='N')
{
cout << "Enter an uppercase letter: ";
cin >> letter;
//This provides the letterPlace value with the possition of the
//input letter by the user within letterNotGuessedYet
letterPlace = letterNotGuessedYet.find(letter,0);
//This statement determines if the letter input by the user is
//still in the letterNotGuessYet string.
if(letterNotGuessedYet.substr(letterPlace,1)== letter)
{
letterNotGuessedYet.replace(letterPlace, 1, "*");
//cout << endl << letterNotGuessedYet; //This tests that a letter is being replaced with an *
}
else
{
cout << "The letter " << letter << " has already been used. Choose another letter." << endl << endl;
}// end if
//search for the letter in the original word
for(int x = 0; x < 5; x++)
{
//if the current character matches
//the letter, replace the corresponding
//dash in the displayWOrd variable and then
//set the dashReplaced variable to 'Y'
if (origWord.substr(x,1) == letter)
{
displayWord.replace(x, 1, letter);
dashReplaced = 'Y';
}//end if
}//end for
//if a dash was replaced, check whether the
//displayWord variable contains any dashes
if (dashReplaced == 'Y')
{
//if the displayWord variable does not
//contain any dashes, the game is over
if (displayWord.find("-",0) == -1)
{
gameOver = 'Y';
cout << endl << "Yes, the word is " << origWord << endl;
cout << "Great guessing!" << endl;
}
else //otherwise, continue guessing
{
cout << endl<< "Guess this word: " << displayWord << endl;
dashReplaced = 'N';
}//end if
}
else //processed when dashReplaced contains 'N'
{
//minus 1 to the number of incorrect gueses left
numIncorrect += 1;
//if the number of incorrect guesses is 10,
//the game is over
if (numIncorrect == 10)
{
gameOver = 'Y';
cout << endl << "Sorry, the word is " << origWord << endl;
}//end if
}//end if
}//end while
//system("pause");
return 0;
}//end of main function
I believe the reason that I'm receiving this error has something to do with the below code:
//This provides the letterPlace value with the possition of the
//input letter by the user within letterNotGuessedYet
letterPlace = letterNotGuessedYet.find(letter,0);
//This statement determines if the letter input by the user is
//still in the letterNotGuessYet string.
if(letterNotGuessedYet.substr(letterPlace,1)== letter)
{
letterNotGuessedYet.replace(letterPlace, 1, "*");
//cout << endl << letterNotGuessedYet; //This tests that a letter is being replaced with an *
}
else
{
cout << "The letter " << letter << " has already been used. Choose another letter." << endl << endl;
}// end if
I am grateful for any assistance that you can bring my way.
The reason you're getting the error is because you are using the "letterPlace" value before you test to see if it was actually found or not. If "string::find" doesn't find anything it will return a value "string::npos". You need to test the letterPlace vairable for this value before trying to use it.
letterPlace = letterNotGuessedYet.find(letter,0);
// Check to see if this letter is still in the "letterNotGuessedYet string
if(letterPlace != string::npos)
{
// At this point the letter is in the letterNotGuessedYet string so let it go
letterNotGuessedYet.replace(letterPlace, 1, "*");
}
else
{
// The letter was not found which means it has already been guessed.
// Show error to the user here
cout << "The letter " << letter << " has already been used. Choose another letter." << endl << endl;
}

On finding vowels and capitals char in the beginning of a string?

I've been making a little memory game as an exercise from a textbook I'm doing. It's called Grandma's trunk and it works by in one turn you found an item in the trunk and the next turn you say you found the previous item and the newest item on this turn...I think.
Mostly it's an exercise on using functions, which I think I've gotten down pretty well. But my output is completely wrong. I've believe I've located the problem in one function where I'm supposed to analyze the first character and decided if it needs an AN or A or THE before the string. There might be a problem with the random function I'm using to throw in predefined items from a small database. The int main() function is supposed to be relatively complete, this is just an exercise to master functions...which I, sorta? Would rather call it novice experience.
I thought that perhaps I was running into the getline bug where it couts a blank line, and from my understanding, is fixed by cin.ignore(); but all that did was force me to press enter twice when I enter data. Which...I sort of like. Perhaps I'm using gizmos like isupper and .at() wrong? I tried using find_first_of but it didn't really change anything.
output calling the storage trunk and the owner grandma and just using word1 word2 word3... wordn....as items found leaves me with the output.
In grandma trunk you've found a
and an ord3 word1.
it completely muddles up the output. I'm starting to think that the int main() body I was given wasn't exactly stellar. But I can't be 100% confident in my article function. Any help would just be incredible. I've been struggling using this among many books and advice from a buddy to teach myself a little about programming. It's been a rather huge headache.
program itself
#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
using namespace std;
string CorrectArticle(string phrase);
string GetPhrase(void);
bool Continue(void);
string UpperCase(string);
string RandomItem(void);
const string PUNCTUATION = ".";
int main(){
//Variables
int turn;
bool flag;
string phrase,
article,
story, item,
storage, owner;
srand(time(NULL));
cout << "Welcome to Grandmother's Trunk 9000" << endl;
cout << "This is a memory game. Each turn a player" << endl;
cout << "Says an item to place inside a trunk. " << endl;
cout << "And the next player has to say what the " << endl;
cout << "previous player said plus his/her own item." << endl;
cout << "This will go around in revolving turns." << endl;
cout << endl << endl;
cout << "But Grandma's Trunk is a little dry..." << endl;
cout << "Let's change what the storage is and " << endl;
cout << "Who owns it." << endl << endl;
//define storage variable
cout << "What exactly is this storage?" << endl;
getline (cin, storage);
cout << "So the items are stored in " << storage << endl;
cout << endl;
//define owner
cout << "Who owns this " << storage << " ?" << endl;
getline (cin, owner);
cout << "The owner is " << owner << endl;
story = "In "+ owner + " " + storage + " you've found ";
turn = 0;
flag = Continue();
//While flag is true
while (flag) {
if (turn %2 == 0) {
item = GetPhrase();
} else {
item = RandomItem();
}
//set corrected item to article
article = CorrectArticle(item);
//advance the story every item
story = story + "\n and " + article + " " + item;
cout << story << PUNCTUATION << endl;
turn++;
flag = Continue();
}
return (0);
}
//Gives A, AN, and THE to correct words
// An if phrase starts with i,e,i,o,u or y
// A if phrase starts with other lower case letters
// The for phrases that start with an uppercase letter
string CorrectArticle(string phrase){
int i=0;
string correctedString;
string stringAn;
string stringA;
string stringThe;
stringAn= " an ";
stringA = " a ";
stringThe= "The ";
if (GetPhrase().at(i) = "a" or "e" or "i" or "u"){
correctedString = stringAn + GetPhrase();
}else if (isupper(GetPhrase().at(i))){
correctedString = stringThe + GetPhrase();
}else{
correctedString = stringA + GetPhrase();
}
return correctedString;
}
//This function takes no parameters
//and returns the user's input
string GetPhrase(void){
string itemInput;
cout << "\nWhat did you find? \n" << endl;
getline (cin, itemInput);
cout << "\nYou found " << itemInput << endl;
cin.ignore();
return itemInput;
}
//Asks user if they wish to continue
bool Continue(void){
//return false if no, true if yes
string continueString;
cout << "Would you like to continue?";
cout << " Yes or No would suffice" << endl;
getline(cin,continueString);
UpperCase(continueString);
cout << "You picked " << continueString;
if (UpperCase(continueString).find("NO") != string::npos){
return false;
} else if (UpperCase(continueString).find("YES") != string::npos){
return true;
}
}
//Changes the string to uppercase
string UpperCase(string stringUpper){
int i = 0;
while (i<stringUpper.size()){
stringUpper[i] = toupper(stringUpper[i]);
i++;
}
return stringUpper;
}
//Randomizes items found in game
string RandomItem(void){
int randomNumber;
int maxNumberOfItems = 5;
string randomizedItem;
randomNumber= rand() % maxNumberOfItems;
switch (randomNumber){
case 0:
randomizedItem = "Smaug";
break;
case 1:
randomizedItem = "Batman";
break;
case 2:
randomizedItem = "Yoda";
break;
case 3:
randomizedItem = "Paul Atreides";
break;
case 4:
randomizedItem = "Captain Kirk";
break;
default:
cout << "ERRORRRR! PANIC!" << endl;
}
return randomizedItem;
}
Remember that = is assignment, == for compare.
Also remember that you have to compare variable with value, such as:
if ((string == "a") or (string == "e") ...
If the or works for you, all the best. I've only been able to use ||. Must be compiler conformity issues.
Try this:
bool is_vowel(char letter)
{
const std::string vowels("aeiouAEIOU");
return (vowels.find_first(letter) != std::string::npos);
}
In other words, I place all the vowels in a string a search the string. If there is a match, the letter is a vowel.

How do I use cin in a while loop?

I'm trying to get the user to input their name(s) using a while loop with an array and cin, but after the last person's name is input, the program crashes instead of moving on. Is there a way to fix this, or do I need to completely change up the code? I'm also fairly new to c++, so can any answers be given as simply as possible?
#include <iostream>
#include <string>
using namespace std;
int main()
{
unsigned int numberofplayers;
number://loop back here if more than 4 players
cout << "Number of players: ";
cin >> numberofplayers;
if(numberofplayers > 4 || numberofplayers < 1){
cout << "Invalid number, please enter a number from 1 to 4." << endl;
goto number;
}
string name[numberofplayers];
cout << "Enter your name" << endl;
int a = 1;
while(a < numberofplayers + 1){
cout << "Player " << a << ": ";
cin >> name[a];
cout << "Hello, " << name[a] << "." << endl;
a++;
}
}
You would probably facing array index out of bound, so Change you while loop to this and set a=0 to fill from 0th index.
while(a < numberofplayers){
}
Your last iteration exceeds the size of the array. You need to change it to
while(a < numberofplayers)
also, on another note, the keyword goto isn't used much anymore. I would suggest using a while there also like
while(true){
cout<<"number of players";
cin>>numberofplayers
if(numberofplayers is valid input){
break;
}
cout<<"bad input";
}
There is a question on stackoverflow discussing the use of goto extensively here:
GOTO still considered harmful?