I don't know if I am overlooking or misunderstanding something, but I am seeing some strange behavior.
I am writing a text based game and have a Player class that is a base for a ConsolePlayer, NetworkPlayer and AIPlayer. I have included a public stringstream object called print so any function can pass data to the player via the familiar insertion operators, i.e.If anyone knows of a better way to handle this, I'm all ears!Code:player.print << "There were " << totalhearts << " hearts." << endl;
My design is that the player objects will all be updated every pulse, and a printStream() function will be called during these updates to extract the output from the stringstream and deliver it to the appropriate mechanism (cout for ConsolePlayer, a send() or queue() function for NetworkPlayer, and push_back() onto a vector for AIPlayer so it can sort through the lines as needed). The extraction process will be the same regardless of the type, and a string will be sent to a function that the child class must overload.
Also, like cout, I only want to send full lines (ending with a newline '\n') except in special circumstances which are outside the scope of this function.
Here is my code:This function is copied exactly from the program, including debug output (like printing the begin, end and size before each line), except that in the class the stringstream is not passed to the function because both are part of the class. This function does the exact same thing in this test program as it does when I compile the skeleton of the game I have so far, so I don't believe the problem is in anything other than this function. I also stripped all the std::'s from the std items and included the using namespace std; just so I could focus on the logic in this simple test program and not have to wade through all the std::'s.Code:#include <string> #include <sstream> #include <iostream> #include <iomanip> using namespace std; void printStream(stringstream &print); int main() { // create a string stream stringstream teststream; teststream << "01 one 789" << endl << "01 two 789" << endl << "0 three 89" << endl << "01 four 89" << endl; // try and print it with the function already written printStream(teststream); return 0; } void printStream(stringstream &print) { // if the print stream is empty, we're done if ( print.str().empty() ) return; string working(print.str()); unsigned int begin = 0; unsigned int end = 0; unsigned int size = working.size(); while ( (end = working.find('\n', begin)) != std::string::npos ) { ++end; // move to one past the \n, substr will then print the \n // and ignore the char one-past it and begin needs to move // to one-past the \n so we don't match the same \n again std::cout << "{b" << setw(3) << begin << ",e" << setw(3) << end << ",s" << setw(3) << size << "} " << working.substr(begin, end); begin = end; } cout << "Begin: " << begin << endl << "End: " << end << endl << "Size: " << size << endl; if (begin == 0) // didn't find a '\n', so didn't print anything { cout << "No \\n's found." << endl; return; } print.clear(); // clear the stream if (begin != size) // if we didn't print the whole thing print.str(working.substr(begin)); //assign the remainder to the stream cout << endl << "string stream ends up as follows:" << endl << ">" << print.str() << "<" << endl; return; }
The cout in the while loop is there only for testing, it will be replaced with a call to the function that must be overloaded by the child classes and will take a single string representing the line of output that was extracted.
I am compiling and running this via g++ version 3.4.4 under cygwin (WinXP). Here is the output I get:As you can see, even though begin and end are pointing to the appropriate places in the string, working.substr(begin, end) is returning far more than it should. Line one is printed just fine, but then lines two and three are printed, and then lines three and four, and so on. I don't understand why this is happening.Code:Asha$ sstest {b 0,e 11,s 44} 01 one 789 {b 11,e 22,s 44} 01 two 789 0 three 89 {b 22,e 33,s 44} 0 three 89 01 four 89 {b 33,e 44,s 44} 01 four 89 Begin: 44 End: 4294967295 Size: 44 string stream ends up as follows: >01 one 789 01 two 789 0 three 89 01 four 89 < Asha$
As an added bonus, print.clear(); apparently fails to do anything at all. I am using it exactly as cppreference.com shows. I replaced it with print.str(""); which works but seems like a kludge to me (though I guess the stringstream probably does the same thing as .clear() before assigning the empty string).
I can't see any reason why this isn't working right. What am I missing?



LinkBack URL
About LinkBacks



"
I used to be an adventurer like you... then I took an arrow to the knee.