What's the equivalent of cout for output to strings? - c++

I should know this already but... printf is to sprintf as cout is to ____? Please give an example.

It sounds like you are looking for std::ostringstream.
Of course C++ streams don't use format-specifiers like C's printf()-type functions; they use manipulators.
Example, as requested:
#include <sstream>
#include <iomanip>
#include <cassert>
std::string stringify(double x, size_t precision)
{
std::ostringstream o;
o << std::fixed << std::setprecision(precision) << x;
return o.str();
}
int main()
{
assert(stringify(42.0, 6) == "42.000000");
return 0;
}

#include <iostream>
#include <sstream>
using namespace std;
int main()
{
ostringstream s;
s.precision(3);
s << "pi = " << fixed << 3.141592;
cout << s.str() << endl;
return 0;
}
Output:
pi = 3.142

Here's an example:
#include <sstream>
int main()
{
std::stringstream sout;
sout << "Hello " << 10 << "\n";
const std::string s = sout.str();
std::cout << s;
return 0;
}
If you want to clear the stream for reuse, you can do
sout.str(std::string());
Also look at the Boost Format library.

std::ostringstream
You can use this to create something like the Boost lexical cast:
#include <sstream>
#include <string>
template <typename T>
std::string ToString( const T & t ) {
std::ostringstream os;
os << t;
return os.str();
}
In use:
string is = ToString( 42 ); // is contains "42"
string fs = ToString( 1.23 ) ; // fs contains something approximating "1.23"

You have a little misunderstanding for the concept of cout. cout is a stream and the operator << is defined for any stream. So, you just need another stream that writes to string in order to output your data. You can use a standard stream like std::ostringstream or define your own one.
So your analogy is not very precise, since cout is not a function like printf and sprintf

Related

Store cout output into variable

How can I store the output from cout into a variable of string or character type?
I have written following code but it doesn't work:
#include<iostream>
#include<stdio.h>
using namespace std;
int main(){
string n;
n = (cout<<"\nHello world");
cout<<n;
return 0;
}
#include <sstream>
std::ostringstream a;
a << "Hello, world!";
std::string b = a.str(); // Or better, `std::move(a).str()`.
std::cout << b;
Other answers have shown you how to capture formatted output using a std::(o)stringstream object directly. But, if for some reason, you really need to capture the output of std::cout, then you can temporarily redirect std::cout to use a std::ostringstream's buffer, eg:
#include <iostream>
#include <sstream>
using namespace std;
int main(){
ostringstream oss;
auto cout_buff = cout.rdbuf(oss.rdbuf());
cout << "\nHello world";
cout.rdbuf(cout_buff);
string n = oss.str();
cout << n;
return 0;
}
Online Demo
Of course there's a way! But you have to use a different kind of stream:
std::ostringstream ss;
ss << "\nHello world";
std::string result = ss.str();
Also, in C++20, you can simply use std::format:
std::string n = std::format("Hello {}! I have {} cats\n", "world", 3);
// n == "Hello world! I have 3 cats\n"

Convert std::ostringstream into std::stringstream

The next code returns an empty string in ss:
#include <string>
#include <iostream>
#include <sstream>
int main () {
std::ostringstream oss;
oss << "Text";
std::stringstream ss;
ss.basic_ios<char>::rdbuf(oss.rdbuf());
std::cout << ss.str() << "\n";
return 0;
}
How can I return from ss the text introduced in oss? I'm mainly interested in converting std::ostringstream into std::stringstream.
You could make use of the protected std::streambuf::swap member function that exchanges the contents of the stream buffer with those of another
To get access to it, you'll need a derived class:
#include <iostream>
#include <sstream>
struct swapper : std::streambuf {
using std::streambuf::streambuf;
void swap(std::streambuf& rhs) { // public proxy for protected swap
std::streambuf::swap(rhs);
}
};
// casting
void swapbuf(std::ostream& a, std::ostream& b) {
static_cast<swapper*>(a.rdbuf())->swap(*b.rdbuf());
}
int main () {
std::ostringstream oss;
oss << "Text";
std::stringstream ss;
swapbuf(oss, ss);
std::cout << "ss: " << ss.str() << "\n"; // prints Text
}
Following comments from #NathanOliver, I decided to convert std::ostringstream into std::stringstream by using str():
#include <string>
#include <iostream>
#include <sstream>
int main () {
std::ostringstream oss;
oss << "Text";
std::stringstream ss;
ss << oss.str();
std::cout << ss.str() << "\n";
return 0;
}

Need help to understand where i am going wrong with strings

In c++ we have std::to_string which converts int/float/double to strings. So just to test my understanding of templates I tried the code below:
#include "iostream"
#include "sstream"
#include "string"
using std::cout;
template <typename T>
std::string getString(const T& data){
std::stringstream ss;
cout << '\n' << data << '\n';
ss << data;
std::string s;
ss >> s;
return s;
}
int main(int argc , char** argv){
cout << getString(1.0000011);
cout <<' '<<std::to_string(1.0000011);
return 0;
}
However, the output doesn't make sense, to_string gives me 1.0000011, whereas getString gets 1 and gives me 1. As I am using templates shouldn't getString get 1.0000011 as well and give me 1.0000011 too?
You can use std::setprecision in the <iomanip> header to set the precision that std::stringstream will use when formatting numeric data.
For example:
std::stringstream ss;
ss << std::setprecision(9) << data;
cout << ss.str();
Will print:
1.0000011
Here's a quick demo online: cpp.sh/9v7xf
As a side note, you don't have to create a string and output from the stringstream - you can replace the last 3 lines in getString() with:
return ss.str();
Numeric values are often truncated for appearance. You can supply the std::fixed manipulator from the iomanip standard header to avoid this issue.
#include "iomanip" // <- Add this header
#include "iostream"
#include "sstream"
#include "string"
using std::cout;
template <typename T>
std::string getString(const T& data)
{
std::stringstream ss;
cout << '\n' << data << '\n';
ss << std::fixed << data;
// ^^^^^^^^^^^^^ Add this
std::string s;
ss >> s;
return s;
}
int main(int argc, char** argv)
{
cout << getString(1.0000011);
cout << ' ' << std::to_string(1.0000011);
return 0;
}
<iomanip> needs included, and std::setprecision must be used when outputting float values to streams. Using your example, this looks like:
#include <iostream>
#include <iomanip> //include this.
#include <sstream>
#include <string>
template <typename T>
std::string getString(const T& data){
std::ostringstream ss;
ss << std::setprecision(8);
std::cout << std::setprecision(8);
std::cout << data << '\n';
ss << data;
return ss.str();
}
int main(int argc , char** argv){
std::cout << getString(1.0000011) << "\n";
std::cout << std::to_string(1.0000011) << std::endl;
return 0;
}
Which prints:
1.0000011
1.0000011
1.000001
Program ended with exit code: 0
Note how to_string alone truncates the floating point number!!! I suspect this is undesired behavior, but to_string cannot be manipulated directly, so...
If desired, you can fix this with the solution found here.
Otherwise, just use std:set_precision() when inserting into streams for precisely converted strings.

Convert a vector<char> to a string with a conversion

I'd like to convert a vector<char> to a std::string and do a conversion one the way.
I'm almost there, but the result of the code below is a vector<string>, while I'd like to have one string (a concatenation of all the string parts in the vector).
See my code example for details.
string ConvertHexToAscii(const char input)
{
std::ostringstream oss;
oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(input);
return oss.str();
}
vector<char> readBuffer; // this is my input
readBuffer.push_back(0x1c);
readBuffer.push_back(0x09);
vector<string> resultVec;
std::transform(readBuffer.begin(), readBuffer.end()
, back_inserter(resultVec)
, ConvertHexToAscii);
// resultVec[0] = "1C";
// resultVec[1] = "09";
The result I need is a string containing "1C09". How to achieve that with std::transform?
You were almost there; this works:
std::stringstream sstr;
std::transform(
input.begin(), input.end(),
std::ostream_iterator<std::string>(sstr, ""),
ConvertHexToAscii);
But unfortunately this instantiates quite a lot of string streams, which is inefficient. Ideally, the ConvertHexToAscii (misnamed, by the way! C++ doesn’t know about encodings) function would directly use the underlying stream.
#include <iostream>
#include <vector>
#include <iomanip>
#include <sstream>
#include <numeric>
std::string ConvertHexToAscii(std::string acc, char input)
{
std::ostringstream oss;
oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(input);
return acc + oss.str();
}
int main() {
std::vector<char> readBuffer; // this is my input
readBuffer.push_back(0x1c);
readBuffer.push_back(0x09);
std::cout << std::accumulate(readBuffer.begin(), readBuffer.end()
, std::string(), ConvertHexToAscii) << std::endl;
return 0;
}
create your own back_insert_iterator (look at the code in your stl lib, it's fairly simple) for string types of which operator = is defined as
template< class string_type, class value_type >
class back_insert_iterator
{
public:
back_insert_iterator< _string_type >& operator = ( const value_type& val )
{
container->append( val )
return *this;
}
};
You can do this with a function output iterator:
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <iterator>
#include <iomanip>
#include <boost/function_output_iterator.hpp>
std::string ConvertHexToAscii(const char input)
{
std::ostringstream oss;
oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(input);
return oss.str();
}
int main() {
std::vector<char> readBuffer; // this is my input
readBuffer.push_back(0x1c);
readBuffer.push_back(0x09);
std::string temp;
std::transform(readBuffer.begin(), readBuffer.end()
, boost::make_function_output_iterator([&temp](const std::string& r) {temp.append(r);})
, ConvertHexToAscii);
std::cout << temp << std::endl;
}
I used a lambda to call the append() function on the result string, but if you don't have that available it's fairly easy to use boost::bind or just write an old fashioned functor to do that for you.
With boost::bind the function output iterator gets created as:
boost::make_function_output_iterator(boost::bind(static_cast<std::string& (std::string::*)(const std::string&)>(&std::string::append), &temp, _1))
instead. It's slightly clunky because you need to pick the right overload for std::string::append.
Whereas perreal's idea of using an accumulation isn't that bad, it may be more performant to operate on the stream directly instead of creating so many temporary strings (though move semantics may help with that):
std::ostringstream os;
std::string temp = std::accumulate(
readBuffer.begin(), readBuffer.end(), std::ref(os),
[](std::ostream &os, const char input)
-> std::reference_wrapper<std::ostream> {
return os << std::hex << std::setw(2)
<< std::setfill('0')
<< static_cast<int>(input);
}).str();
EDIT: But Ok, that's maybe a bit oversophistication here, a simple foreach would have done, too (even if not as semantically clean as an accumulation):
std::ostringstream os;
std::for_each(readBuffer.begin(), readBuffer.end(),
[&os](const char input) mutable {
os << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(input);
});
std::string temp = os.str();
But anything might be better than creating a whole bunch of temporary strings.

C++: something is getting sent to the console: how do I, instead, store it to a variable?

string convert_binary_to_hex(string binary_value)
{
bitset<8> set(binary_value);
cout << hex << set.to_ulong() << endl; // this is the output that I want to store to a variable to return
return "";
}
I've not really done C before. =D
EDIT:
a user suggested ostringstream:
ostringstream result;
bitset<8> set(binary_value);
result << hex << set.to_ulong() << endl;
return result.str();
but it now give this error:
main.cpp:20: error: aggregate ‘std::ostringstream result’ has incomplete type and cannot be defined
Also, my imports:
#include <stdio.h>
#include <iostream>
#include <string>
#include <bitset>
using namespace std;
Write it to an instance of std::ostringstream:
string convert_binary_to_hex(string binary_value)
{
bitset<8> set(binary_value);
ostringstream oss;
oss << hex << set.to_ulong() << endl; // this is the output that I want to store to a variable to return
return oss.str();
}
See this answer:
C++ equivalent of sprintf?
And use the out variable like you're using cout here, and instead of
std::cout << out.str() << '\n';
you would just do
return out.str();