converting a string to an array of words

Discussion in 'C++' started by Frederik Van Bogaert, Apr 19, 2007.

  1. Hi! I've taken my first steps into the world of c++ by trying to write a
    text adventure game. Things are proceeding fine, but there's some code
    in there that isn't very well coded. More specifically, I use the
    following code:

    ...
    string word [4];
    size_t pos = action.find(" ");
    word[0] = action.substr (0,pos);
    if (pos < action.size() - 2)
    {
    word[1] = action.substr(pos + 1);
    }
    string word1 [2];

    for (int i=1;i<3;i++)
    {
    pos = word.find(" ");
    if (pos == string::npos) goto skippy;
    word1[i-1] = word.substr (0,pos);
    if (pos < word.size() - 2)
    {
    word[i+1] = word.substr(pos + 1);
    }
    word = word1[i-1];
    }

    skippy:
    ...

    To convert a string called 'action' into the array word[4]. Is there a
    way to do this more efficiently?
    Thanks
     
    Frederik Van Bogaert, Apr 19, 2007
    #1
    1. Advertisements

  2. Not sure about efficiency. But elegance is relatively easy to come by.
    All you need to do is take your string, construct a stringstream out of
    it and then read all the words from it until end-of-file.

    V
     
    Victor Bazarov, Apr 19, 2007
    #2
    1. Advertisements

  3. Frederik Van Bogaert

    Jim Langston Guest



    Use. std::stringstream. stringstream will read using >> like std::cin,
    stopping on spaces.

    Output of following program is:

    look
    at
    the
    clock
    on
    the
    wall

    #include <iostream>
    #include <string>
    #include <vector>
    #include <sstream>

    // typedef is not required, just makes it a little eaiser.
    typedef std::vector<std::string> WordVec;

    int main()
    {
    std::string action = "look at the clock on the wall";

    WordVec Words;
    // Following declares a stringstream Parse and initializes it to the
    contents of action
    std::stringstream Parse( action );

    // Now we read each word out one by one til there's no more and stuff
    them into our vector
    std::string word;
    while ( Parse >> word )
    Words.push_back( word );

    // At this point each word is in the vector.

    for ( WordVec::iterator it = Words.begin(); it != Words.end(); ++it )
    std::cout << (*it) << "\n";

    std::string wait;
    std::getline( std::cin, wait );
    }
     
    Jim Langston, Apr 19, 2007
    #3

  4. Thanks! That's exactly what I was looking for :)

    PS: Is there some reason you're using "std::" all the time instead of
    specifying "using namespace std;" in the beginning of the file as I've
    been told to do?
     
    Frederik Van Bogaert, Apr 19, 2007
    #4
  5. Replace the three lines above with this:

    std::copy(std::istream_iterator<std::string>(Parse),
    Replace the loop with this:

    std::copy(Words.begin(), Words.end(),
    And you get an even more radical standard-library based program!

    V
     
    Victor Bazarov, Apr 19, 2007
    #5
  6. Frederik Van Bogaert

    Jim Langston Guest



    Because I feel that "using namespace std;" defeats the purpose of namespaces
    to begin win. Check out the FAQ:

    http://www.parashift.com/c++-faq-lite/coding-standards.html#faq-27.5
     
    Jim Langston, Apr 19, 2007
    #6
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.