Monday, April 25, 2011

How do you read a word in from a file in C++?

So I was feeling bored and decided I wanted to make a hangman game. I did an assignment like this back in high school when I first took C++. But this was before I even too geometry, so unfortunately I didn't do well in any way shape or form in it, and after the semester I trashed everything in a fit of rage.

I'm looking to make a txt document and just throw in a whole bunch of words (ie: test love hungery flummuxed discombobulated pie awkward you get the idea )

So here's my question: How do I get C++ to read a random word from the document?

I have a feeling #include<ctime> will be needed, as well as srand(time(0)); to get some kind of pseudorandom choice...but I haven't the foggiest on how to have a random word taken from a file...any suggestions?

Thanks ahead of time!

From stackoverflow
  • I would recommend creating a plain text file (.txt) in Notepad and using the standard C file APIs (fopen(), and fread()) to read from it. You can use fgets() to read each line one at a time.

    Once you have your plain text file, just read each line into an array and then randomly choose an entry in the array using the method you've suggested above.

    Jeff : didn't mean it to seem like I wanted to use word, .txt was the intent. I tried to place a new line between each of those examples but it seemed to not work. Could you please explain what you mean? I looked at those two links but I didn't quite understand them.
    jeffamaphone : You may find the iostream example posted by TrayMan easier to use than the C APIs. I don't think I can explain it in this little box.
    Jeff : fair enough, thank you for the idea though!
    Arafangion : Beware that Notepad does not neccessarily save in ASCII format.
  • Here's a rough sketch, assuming that the words are separated by whitespaces (space, tab, newline, etc):

    vector<string> words;
    ifstream in("words.txt");
    while(in) {
      string word;
      in >> word;
      words.push_back(word);
    }
    
    string r=words[rand()%words.size()];
    
    jeffamaphone : Be sure to #include .
    Jeff : Understood...so 'in' does the same as 'infile'? Or are those two different things?
    Jeff : And simply out of curiosity and the fact I've not seen it before, what is the push_back() doing? Afraid I've not seen that command before
    TrayMan : It inserts the value to the end of the vector. There's also a push_front.
    dalle : The push_back member function of std::vector adds an element (in this case a string) to the end of the vector.
    jeffamaphone : See the following vector<> reference. This is the sugary C++ way of doing things. http://www.cplusplus.com/reference/stl/vector/
    Arafangion : "in" here is nothing more than a name for a variable that TrayMan decided to use. He could've used 'foo', 'bar', 'cheese', or even 'stackoverflow_input_argument'.
    Vadi : Unfortunetly, this code does not work in vc++ compiler.
  • The operator >> used on a string will read 1 (white) space separated word from a stream.

    So the question is do you want to read the file each time you pick a word or do you want to load the file into memory and then pick up the word from a memory structure. Without more information I can only guess.

    Pick a Word from a file:

    // Note a an ifstream is also an istream. 
    std::string pickWordFromAStream(std::istream& s,std::size_t pos)
    {
        std::istream_iterator<std::string> iter(s);
        for(;pos;--pos)
        {    ++iter;
        }
    
        // This code assumes that pos is smaller or equal to
        // the number of words in the file
        return *iter;
    }
    

    Load a file into memory:

    void loadStreamIntoVector(std::istream& s,std::vector<std::string> words)
    {
        std::copy(std::istream_iterator<std::string>(s),
                  std::istream_iterator<std::string>(),
                  std::back_inserter(words)
                 );
    }
    

    Generating a random number should be easy enough. Assuming you only want psudo-random.

0 comments:

Post a Comment