These threads do NOT answer me:
How do you clear a stringstream variable?
std::ifstream file( szFIleName_p );
if( !file ) return false;
// create a string stream for parsing
std::stringstream szBuffer;
std::string szLine; // current line
std::string szKeyWord; // first word on the line identifying what data it contains
while( !file.eof()){
// read line by line
std::getline(file, szLine);
// ignore empty lines
if(szLine == "") continue;
szBuffer.str("");
szBuffer.str(szLine);
szBuffer>>szKeyWord;
szKeyword
will always contain the first word, szBuffer
is not being reset, can't find a clear example anywhere on how to use stringstream.
New code after answer:
...
szBuffer.str(szLine);
szBuffer.clear();
szBuffer>>szKeyWord;
...
Ok, thats my final version:
std::string szLine; // current line
std::string szKeyWord; // first word on the line identifying what data it contains
// read line by line
while( std::getline(file, szLine) ){
// ignore empty lines
if(szLine == "") continue;
// create a string stream for parsing
std::istringstream szBuffer(szLine);
szBuffer>>szKeyWord;
You didn't clear()
the stream after calling str("")
. Take another look at this answer, it also explains why you should reset using str(std::string())
. And in your case, you could also reset the contents using only str(szLine)
.
If you don't call clear()
, the flags of the stream (like eof
) wont be reset, resulting in surprising behaviour ;)
It depends what you're doing with it. It's generally easier to just
create a new istringstream
or ostringstream
. To "reset" a stream,
you have to clear its buffer, clear any error flags, reset any
formatting flags, plus the precision and fill, reimbue
it with the
original locale, and not forget any extended formatting information
generated with a value returned from xalloc
. In sum, impossible to
get correct.
And while I'm at it, your loop is wrong, and will probably result in the
last line being processed twice. file.eof()
only has a usable meaning
after the input has failed (and even then, it's not 100% reliable).
What you want is:
std::string line;
while ( std::getline( file, line ) ) {
if ( !line.empty() ) {
std::istringstream buffer( line );
// ...
}
}
(Actually, you probably want to trim trailing white space from the line before the test for empty.)
In most cases, it is easier to create a new istringstream
or ostringstream
instead of resetting the same ones.
However, if you do want to resent them:
Resent flags of the stream (to avoid unexpected behavior) using
clear ()
.While you can correct the contents of your
stringstream
usingstr ("")
, for efficiency purposes we might preferstr(std::string())
.
ss is stringstream. Use
- first step: ss.clear();
- second step: ss.str("");
to reuse the stringstream -- completely clear the string stream.
If you have the stream in a class member,
use unique_ptr<stringstream>
,
then just reset(new stringstream(...))
to reuse it.
Imagine a config file.
par1=11
par2=22
codes:
std::string line, strpar1, strpar2;
int par1, par2;
std::ifstream configfile("config.cfg");
std::getline(configfile, line); // first line to variable "line"
std::istringstream sline(line);
while (std::getline(sline, strpar1, '='));
par1 = std::stoi(strpar1); // par1 get 11
bool b = sline.eof(); // true
std::getline(configfile, line); // second line to variable "line"
sline.clear(); //
sline.str(line); // reuse "sline"
b = sline.good(); // true // goodbit is zero, indicating that none of the other bits is set.
b = sine.fail(); // false
b = sline.bad(); // false
b = sline.eof(); // false
while (std::getline(sline, strpar2, '='));
par2 = std::stoi(strpar2); // par2 get 22
goodbit is zero, indicating that none of the other bits is set
来源:https://stackoverflow.com/questions/12112259/how-to-reuse-stringstream