How do you clear a stringstream variable?
For all the standard library types the member function empty()
is a query, not a command, i.e. it means "are you empty?" not "please throw away your contents".
The clear()
member function is inherited from ios
and is used to clear the error state of the stream, e.g. if a file stream has the error state set to eofbit
(end-of-file), then calling clear()
will set the error state back to goodbit
(no error).
For clearing the contents of a stringstream
, using:
m.str("");
is correct, although using:
m.str(std::string());
is technically more efficient, because you avoid invoking the std::string
constructor that takes const char*
. But any compiler these days should be able to generate the same code in both cases - so I would just go with whatever is more readable.
How to clear stringstream?
Typically to 'reset' a stringstream you need to both reset the underlying sequence to an empty string with str
and to clear any fail and eof flags with clear
.
parser.str( std::string() );
parser.clear();
Typically what happens is that the first >>
reaches the end of the string and sets the eof bit, although it successfully parses the first short. Operations on the stream after this immediately fail because the stream's eof bit is still set.
Best way to empty stringstream?
I've always done:
s.clear();//clear any bits set
s.str(std::string());
@litb gets into more detail about how to seekp to the start of the stream combined with std::ends you can keep your allocated size.
resetting a stringstream
This is the way I usually do it:
ss.str("");
ss.clear(); // Clear state flags.
Why do I need to clear a stringstream variable with each iteration of a loop in which it is used
The rationale behind this is that creating heavy objects inside of the loop leads to performance degradation. ::std::stringstream
is one of these objects and it's a common mistake to create and destroy string streams all the time. However such a rule does not apply for light objects, such as primitive types.
Consider the test case:
#include <chrono>
#include <sstream>
#include <iostream>
#include <cstdlib>
int main()
{
using namespace std;
using namespace chrono;
auto const loops_count{1000000};
auto const p1{high_resolution_clock::now()};
{
stringstream ss{};
for(auto i{loops_count}; 0 != i; --i)
{
ss.str(string{}); // clear
ss << 1;
}
}
auto const p2{high_resolution_clock::now()};
{
for(auto i{loops_count}; 0 != i; --i)
{
stringstream ss{}; // recreate
ss << 1;
}
}
auto const p3{high_resolution_clock::now()};
cout << duration_cast< milliseconds >(p2 - p1).count() << "ms "
<< duration_cast< milliseconds >(p3 - p2).count() << "ms"
<< endl;
return EXIT_SUCCESS;
}
first loop 35ms, second 431ms
how to clear the content in the String stream.?
What you're doing is clearing the string that is returned from the stringstream, not the internal string. You'll have to actually do the ss.str("")
See here:
How do you clear a stringstream variable?
How to properly empty stringstream buffer?
The problem you are having is that calling buffer.str("")
doesn't reset the stream state flags so if a previous operation failed or reached the end of the stream no other reads will succeed. The following should fix the issue:
buffer.str("");
buffer.clear();
Your code seems unnecessarily convoluted. If all you are trying to do is convert dates to and from strings I recommend using Howard Hinnant's date library which is now also part of c++20.
Clear and reuse a stringstream for multiple conversions
You can call the str(s)
method to initialize an std::istringstream
to a new string. You should use std::istringstream
if all you're doing is converting from a string.
If the previous conversion resulted in an error you will also need clear()
, to clear its error state.
So your example would be:
istringstream ss(hour);
ss >> i_hour;
ss.clear();
ss.str(minute);
ss >> i_minute;
Using .clear() in string streams (C++)
After you do inSS >> userAge;
the first time, that involves trying to read past the end of the string, since it had to see if there was another digit after the last digit of the age.
This means the eofbit
is set on the stream, which means future extractions will fail due to the stream being in an end-of-file state. The clear()
call clears this state.
You should find that if you provide an input string the first time around that can extract userAge
without hitting the end (e.g. joe shmo 23 foo
) then the clear()
call is not necessary (but it's still good practice).
BTW it would be good practice to test if (!inSS)
to check for errors after inSS >> userAge
otherwise you go on to output "garbage" values in the form of whatever values the variables already had, since the read attempt failed.
Related Topics
How to Link to a Library With Code::Blocks
When Is the "Typename" Keyword Necessary
Why Is It Wrong to Use Std::Auto_Ptr≪≫ With Standard Containers
Why Should the Copy Constructor Accept Its Parameter by Reference in C++
When to Use Inline Function and When Not to Use It
What Is the Point of Function Pointers
How to Determine the Version of the C++ Standard Used by the Compiler
Why Pass by Const Reference Instead of by Value
What Is the Meaning of Prepended Double Colon "::"
How Does C++ Handle &&? (Short-Circuit Evaluation)
Difference Between Static_Cast≪≫ and C Style Casting
C++ Deprecated Conversion from String Constant to 'Char*'
Namespace + Functions Versus Static Methods on a Class