What's the Difference Between Istringstream, Ostringstream and Stringstream/Why Not Use Stringstream in Every Case

What's the difference between istringstream, ostringstream and stringstream? / Why not use stringstream in every case?

Personally, I find it very rare that I want to perform streaming into and out of the same string stream.

Usually I want to either initialize a stream from a string and then parse it; or stream things to a string stream and then extract the result and store it.

If you're streaming to and from the same stream, you have to be very careful with the stream state and stream positions.

Using 'just' istringstream or ostringstream better expresses your intent and gives you some checking against silly mistakes such as accidental use of << vs >>.

There might be some performance improvement but I wouldn't be looking at that first.

There's nothing wrong with what you've written. If you find it doesn't perform well enough, then you could profile other approaches, otherwise stick with what's clearest. Personally, I'd just go for:

std::string stHehe( "Hello stackoverflow.com!" );

Should I use string or ostringstream or stringstream for fileIO in C++

Assuming that there are at least some operation and that you are not copying twice the same data to end with an unchanged file, the possible improvements (IMHO) are:

  • do not use std::endl inside a loop, but only '\n' or "\n". std::endl does write an end of line, but also force an flush on the underlying stream which is useless and expensive inside a loop.
  • you code copies the data twice. It is much more efficient if possible to build a temp file by copying (as your code currently does) and then remove the old file and rename the temp one with the original name. That way you only copy once the data, because renaming a file is a cheap operation.

Understanding stringstream

There's a constructor for std::stringstream that takes a std::string as a parameter and initializes the stream with that value.

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

int main() {

std::stringstream ss("foo bar");

std::string str1, str2;
ss >> str1 >> str2;

std::cout << "str1: " << str1 << std::endl;
std::cout << "str2: " << str2 << std::endl;

}

This code initializes a stringstream, ss, with the value "foo bar" and then reads it into two strings, str1 and str2, in the same way in which you would read from a file or std::cin.

stringstream or ostringstream for writing in file?

people here say that we should use ostringstream over the stringstream if we deal only with output operations

The main reason for using the more specific ostringstream is to make your intentions clear and avoid mistakes. In this case stringstream is needed to prevent copying a potentially large string, so just use it (carefully).

What exactly does stringstream do?

Sometimes it is very convenient to use stringstream to convert between strings and other numerical types. The usage of stringstream is similar to the usage of iostream, so it is not a burden to learn.

Stringstreams can be used to both read strings and write data into strings. It mainly functions with a string buffer, but without a real I/O channel.

The basic member functions of stringstream class are

  • str(), which returns the contents of its buffer in string type.

  • str(string), which set the contents of the buffer to the string argument.

Here is an example of how to use string streams.

ostringstream os;
os << "dec: " << 15 << " hex: " << std::hex << 15 << endl;
cout << os.str() << endl;

The result is dec: 15 hex: f.

istringstream is of more or less the same usage.

To summarize, stringstream is a convenient way to manipulate strings like an independent I/O device.

FYI, the inheritance relationships between the classes are:

string stream classes

Stringstream weird behaviour

As we know now, + is a valid token for a double, so you need a way to skip to the next space-separated token instead of just getting rid of it. This function can do it for you:

template<class Ct>
std::basic_istream<Ct>& next_token(std::basic_istream<Ct>& is) {
is.clear();
std::ctype<Ct> const& ctype = std::use_facet<std::ctype<Ct>>(is.getloc());
if (ctype.is(ctype.space, is.peek())) {
return is >> std::ws;
}
Ct c;
while (is.get(c) && !ctype.is(ctype.space, c)) {
;
}
return is;
}

Then you can change your code to:

stringstream sso("12 + 1442 nana 7676");
double num = 0;
while (sso) {
if (!(sso >> num)) {
sso >> next_token;
} else {
cout << num << endl;
}
}

Output:

12
1442
7676

Unable to use stringstream to read in int and double

``
#include <iostream>
#include <sstream>//for istringstream
//Using stringstream to read in multiple arguments
int main(){

std::istringstream iss;
std::string tempSTR;
int A;
double B;
std::cout<<"Please enter an int.\n";
std::cin>>tempSTR;
iss.str(tempSTR);
iss>>A;
iss.clear();
std::cout<<"A = "<<A<<"\n";
std::cout<<"Please enter a double.\n";
std::cin>>tempSTR;
iss.str(tempSTR);
iss>>B;
iss.clear();
std::cout<<"B = "<<B<<"\n";

std::cout<<"\nEND OF PROGRAM. GOODBYE!\n\n";
}//end of main
``
//Question:Unable to use stringstream to read in int and double
//Answer:stream just needed to be cleared before using it to read in another argument.

Why does stringstream change value of target on failure?

From this reference:

If extraction fails (e.g. if a letter was entered where a digit is expected), value is left unmodified and failbit is set (until C++11)

If extraction fails, zero is written to value and failbit is set. If extraction results in the value too large or too small to fit in value, std::numeric_limits::max() or std::numeric_limits::min() is written and failbit flag is set. (since C++11)

It seems that your compiler is compiling in C++11 mode, which changes the behavior.


The input operator uses the locale facet std::num_get whose get function invokes do_get. For C++11 it's specified to use std::strtoll et. al. type of functions. Before C++11 it apparently used std::scanf style parsing (going by the reference, I don't have access to the C++03 specification) to extract the numbers. The change in behavior is due to this change in parsing the input.



Related Topics



Leave a reply



Submit