I wrote a Hangman game to try out some of the new features in C++11. I'm pretty new to C++, and I would like some good advice on how I can improve this code (in terms of conventions, bad/good practices, ...):#include <iostream>#include <fstream>#include <vector>#include <string>#include <stdexcept>#include <random>#include <algorithm>const unsigned initial_number_of_lives = 5;// Returns a random word from the given words file.std::string pick_word(const std::string& words_filename) {  std::vector<std::string> words;  std::ifstream words_file(words_filename.c_str());  if (!words_file) {    throw std::runtime_error(Couldn't open file.);  }  std::string word;  do {    std::getline(words_file, word);    words.push_back(word);  } while (!words_file.eof());  std::uniform_int_distribution<uintmax_t> random_distribution(0, words.size() - 1);  std::mt19937 random_engine(static_cast<std::mt19937::result_type>(std::time(nullptr)));  uintmax_t word_index = random_distribution(random_engine);  return words[word_index];}int main(int argc, const char *argv[]) {  if (argc != 2) {    std::cerr << usage:  << argv[0] <<  <words-file>\n;    return 1;  }  std::string word;  try {    word = pick_word(argv[1]);  } catch(...) {    std::cerr << argv[0] << : couldn't open words file:  << argv[1] << '\n';    return 1;  }#if DEBUG  std::cout << (debug) word:  << word << \n\n;#endif  std::cout << Welcome to hangman!; // Newline in main loop below.  unsigned lives = initial_number_of_lives;  std::vector<char> guessed_letters;  for (;;) {    bool won = true;    for (char &letter : word) {      if (std::find(guessed_letters.begin(),                    guessed_letters.end(),                    letter) == guessed_letters.end()) {        won = false;      }    }    if (won) {      std::cout << You won the game!!1\n;      return 0;    }    std::cout << \n\nLives left:  << lives;    std::cout << \nAlready guessed: ;    for (char &letter : guessed_letters) {      std::cout << letter << ' ';    }    std::cout << '\n';    for (char &letter : word) {      if (std::find(guessed_letters.begin(),                    guessed_letters.end(),                    letter) != guessed_letters.end()) {        std::cout << letter;      } else {        std::cout << '_';      }    }    char guess;    std::cout << \nEnter a letter: ;    std::cin >> guess;    guess = std::tolower(guess);    // Don't allow player to enter the same letter twice.    if (std::find(guessed_letters.begin(),                  guessed_letters.end(),                  guess) != guessed_letters.end()) {      std::cout << You have already guessed that letter!\n;      continue;    }    // Don't allow player to enter anything but letters.    if (!std::isalpha(guess)) {      std::cout << That is not a letter!\n;      continue;    }    guessed_letters.push_back(guess);    bool word_contains_letter = false;    for (char &letter : word) {      if (letter == guess) {        word_contains_letter = true;        break;      }    }    if (word_contains_letter) continue;    --lives;    if (lives == 0) {      std::cout << Game over! The right word was:  << word << '\n';      break;    }  }  return 0;}
Testing new C++11 features with Hangman
c++;beginner;c++11;hangman
A few thoughts:Instead of do {    std::getline(words_file, word);    words.push_back(word);} while (!words_file.eof());You should dowhile(std::getline(words_file, word))    words.push_back(word);}Otherwise, the read which causes the stream to go into an invalid state will still be pushed.Also, why not include the filename that cannot be opened in the exception text and then output the exception text instead of the hard-coded text you have now.  As things are, you may be ignoring other exceptions (although I don't see when one would happen).  Perhaps output the exception.what() in addition to what you have now.I would also advise splitting some of the game logic into functions -- you don't need them in multiple places as things are, but it could be easier to follow.  Things like the piece setting word_contains_letter would look better as function calls, in my opinion.Oh, another thing:  you may want to use #ifndef NDEBUG rather than #ifdef DEBUG, as that is the default way to check whether debugging is enabled or not.