Thread: parsing words out of a string?

  1. #1
    Registered User
    Join Date
    Mar 2002
    Posts
    203

    parsing words out of a string?

    I'm trying to parse the first words out of a string and i've comeup with this:
    Code:
    #include <string>
    #include <iostream>
    
    
    using namespace std;
    
    int main()
    {
    	string Input = "/kick name the reason";
    	string Command, CommandTarget, CommandData, ParseString;
    
    	ParseString = Input;
    	Command = ParseString.substr(0, ParseString.find(" "));
    	ParseString = ParseString.substr(ParseString.find(" ")+1);
    	CommandTarget = ParseString.substr(0, ParseString.find(" "));
    	ParseString = ParseString.substr(ParseString.find(" ")+1);
    	CommandData = ParseString;
    	cout << "Input: " << Input << endl;
    	cout << "Command: " << Command << endl;
    	cout << "Target: " << CommandTarget << endl;
    	cout << "Data: " << CommandData << endl;
    
    	Input = "/kick name";
    
    	ParseString = Input;
    	Command = ParseString.substr(0, ParseString.find(" "));
    	ParseString = ParseString.substr(ParseString.find(" ")+1);
    	CommandTarget = ParseString.substr(0, ParseString.find(" "));
    	ParseString = ParseString.substr(ParseString.find(" ")+1);
    	CommandData = ParseString;
    	cout << "Input: " << Input << endl;
    	cout << "Command: " << Command << endl;
    	cout << "Target: " << CommandTarget << endl;
    	cout << "Data: " << CommandData << endl;
    
    
    	system("pause");
    	return 0;
    }
    Would this be a good way to do it? All those calls to find and substr seems like it'd be slower than it needs to.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You can use a stringstream to parse as well. If the words are separated by whitespace, just use operator>>.

  3. #3
    Registered User
    Join Date
    Mar 2002
    Posts
    203
    Ok, but how would I parse the rest of the string from the stream including whitespaces. Like in the first section of the sample code, "the reason" contains whitespaces but it all needs to go into the CommandData string. In the second section of the sample code, CommandData should be empty. It'll be empty so I can check if anything was sent, but that's all going to be done after the string is parsed.

  4. #4
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    string s1;
    string s2;
    string rest;
    stringstream str("part1 part2 and the rest of it");
    str >> s1 >> s2;
    getline(str, rest);
    Kurt

    EDIT: to skip leading whitespace in rest you could use
    Code:
    str >> s1 >> s2 >> ws;
    Last edited by ZuK; 02-01-2006 at 03:29 PM.

  5. #5
    Super Moderater.
    Join Date
    Jan 2005
    Posts
    374
    I rather like this example from the FAQ

    Code:
    #include <string> 
    #include <iostream> 
    #include <vector> 
    int main(void)
    {
      std::string numbers_str = "zero,one,two,three,four,five,six,seven,eight,nine,ten";
      std::vector < std::string > numbers; //we'll put all of the tokens in here 
      std::string  temp;
    
      while (numbers_str.find(",", 0) != std::string::npos)
      { //does the string a comma in it?
        size_t  pos = numbers_str.find(",", 0); //store the position of the delimiter
        temp = numbers_str.substr(0, pos);      //get the token
        numbers_str.erase(0, pos + 1);          //erase it from the source 
        numbers.push_back(temp);                //and put it into the array
      }
    
      numbers.push_back(numbers_str);           //the last token is all alone 
      std::cout << "Number " << 3 << " is " << numbers[3] << std::endl;
    
      return(0);
    }
    http://faq.cprogramming.com/cgi-bin/...&id=1044780608

    There's also an example for doing something similar in C.

  6. #6
    Registered User
    Join Date
    Mar 2002
    Posts
    203
    thanks for the FAQ link. I didn't know what a token was so I didn't open the link when i searched parse. And Thanks everyone for suggesting streamstring. I just recently switched from only using char arrays to using strings.

  7. #7
    Registered User
    Join Date
    Mar 2002
    Posts
    203
    Sorry, one more question. Can you add a string to a stringstream that has been declared alread?

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Yes, use the str() function to reset the data inside the stringstream to whatever you pass to it. If you want to add on to the existing string, it might be more complicated, although it may be as simple as using operator<<.

  9. #9
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    The stringstream member function str() can be used to both obtain the string contained in the stringstream as well as to set the string inside the stringstream.

    If you want to add on to the existing string, it might be more complicated, although it may be as simple as using operator<<.
    I get some funny results when trying to add onto an ostringstream(VC++6). Is this what you are talking about:
    Code:
    string content = "hello";
    string toAdd = "world";
    
    ostringstream oStrStrm;
    oStrStrm<<content;
    cout<<oStrStrm.str()<<endl;  //hello
    
    oStrStrm<<" "<<toAdd;
    cout<<oStrStrm.str()<<endl;  //hello world
    
    //but this doesn't work as expected:
    ostringstream outStr(content);
    cout<<outStr.str()<<endl;  //hello
    outStr<<" "<<toAdd;
    cout<<outStr.str()<<endl;  // world(hello was overwritten)
    
    //this does work:
    ostringstream outStr2;
    outStr2<<content<<" "<<toAdd;
    cout<<outStr2.str()<<endl;  //hello world
    Last edited by 7stud; 02-01-2006 at 08:23 PM.

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I was thinking of using a straight stringstream (not ostringstream or istringstream), and mixing >> and <<. I don't know if the language allows this, or if any particular compiler handles it correctly.
    Code:
    stringstream strStrm("Hello World Goodbye");
    string firstWord;
    strStrm >> firstWord;
    strStrm << firstWord;
    cout << strStrm.str();  // " World GoodbyeHello" ??
    Don't have time to test it right now.

  11. #11
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    @ Daved : It's not that easy. To get the effect you want you have to manipulate the get and put positions of the stringstream. Reading from the stringstream does not change the contents returned by str(), but you can read from the current get-position to the end using getline().
    like that
    Code:
       stringstream strStrm("Hello World Goodbye");
       string firstWord;
       strStrm >> firstWord;
       strStrm.seekp(0, ios::end);
       strStrm  << firstWord;
       string manipulated;
       getline( strStrm, manipulated );
       cout << manipulated << endl;
    my output:
    Code:
     World GoodbyeHello
    Kurt

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    OK, thanks. Hopefully the OP just wants to reset the stream's value, which would be much less of a hassle.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. OOP Question DB Access Wrapper Classes
    By digioz in forum C# Programming
    Replies: 2
    Last Post: 09-07-2008, 04:30 PM
  2. Replies: 8
    Last Post: 04-25-2008, 02:45 PM
  3. Inheritance Hierarchy for a Package class
    By twickre in forum C++ Programming
    Replies: 7
    Last Post: 12-08-2007, 04:13 PM
  4. String Class
    By BKurosawa in forum C++ Programming
    Replies: 117
    Last Post: 08-09-2007, 01:02 AM
  5. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM