How can I reverse the output stream in c++? - c++

What I am trying to achieve is to use the standard std::cout and if you understand, reverse the output to an input so another part of my program can read it. No I cannot just call a function in the other part of my program because every function is and must stay private so this seems the only way to do it. I did a similar thing in java by redirecting the default output stream to my own custom one but I am somewhat new to c++. This is what I did in java:
System.setOut(customPrintStream);
Does anyone know of an alternative for c++ or a way to get whatever is printed to console?

The c++ standard library supports the concept of 'reverse iterators'.
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
int main()
{
auto s = std::string("Hello, World");
std::copy(std::rbegin(s), std::rend(s),
std::ostream_iterator<char>(std::cout));
std::cout << std::endl;
return 0;
}
expected output:
dlroW ,olleH

The streams in C++ read from and write to std::streambuf objects. You can replace the stream buffer of an std::ostream object using the rdbuf() function. For example, to capture all output written to std::cout in a std::string you could use something like this:
std::ostreamstream stream;
std::streambuf* sbuf = std::cout.rdbuf(stream.rdbuf());
// use code whose output is written to `std::cout`
std::cout.rdbuf(sbuf); // restore the original stream buffer
std::string output = stream.str();
In a real implementation you'd probably use an RAII approach to replace/restore the stream buffer. Also, you might want to use a custom stream buffer rather than a std::stringbuf but the basic remain as is.

Related

Transform a buffer into an istream to work in existing programs

I am trying to create a native nodejs module, using NAN and c ++, I want to transform an existing program that uses std::ifstream stream (filename, std :: ifstream :: in | std :: ifstream :: binary); to load a file into a javascript module that can load a buffer and send it to c ++
The original c ++ code was made to work via command line, I don't want to have to write a file to disk, I would like to send this file using a nodejs buffer.
index.js
const fs = require('fs')
const addon = require('./build/Release/image_edit');
fs.readFile('image.png', function read(err, buffer) {
if (err) {
throw err;
}
var result = addon.edit(buffer, buffer.length);
//console.log(result)
});
main.cpp
#include <node.h>
#include <node_buffer.h>
#include <iostream>
#include <nan.h>
#include <sstream>
#include <string>
#include <fstream>
#include <streambuf>
#include <istream>
using namespace Nan;
using namespace v8;
uint32_t read(std::istream& in)
{
uint32_t v;
in.read(reinterpret_cast<char*>(&v), sizeof(v));
return v;
}
NAN_METHOD(edit) {
unsigned char*buffer = (unsigned char*) node::Buffer::Data(info[0]->ToObject());
unsigned int size = info[1]->Uint32Value();
//the closest I could to manipulating the data was using a vector
std::vector<uint32_t> png_data(buffer, buffer + size);
//The main core of the program uses the in.read function to parse the file, tb uses in.clear () and in.seekg ();
//here an example of how this is done
uint32_t count = readU32(stream);
}
NAN_MODULE_INIT(Init) {
Nan::Set(target, New<String>("edit").ToLocalChecked(),
GetFunction(New<FunctionTemplate>(edit)).ToLocalChecked());
}
NODE_MODULE(image_edit, Init)
I tried using the following code to verify that the data received is valid and if the recorded file is the same as the original, everything looks fine.
std::ofstream FILE("test.png", std::ios::out | std::ofstream::binary);
std::copy(png_data.begin(), png_data.end(), std::ostreambuf_iterator<char>(FILE));
The question is, how do I make this buffer received from nodejs into something read the same way an ifstream does, without having to drastically change the c ++ program?
The main methods called by the program in c ++ are: .seekg (), .push_back, .clear (),
This kind of thing is usually done by implementing a custom subclass of std::streambuf, and then using it to construct a std::istream.
std::istream has a constructor that takes a pointer to a std::streambuf as a parameter, so the basic outline is something like this
class my_streambuf : public std::streambuf {
// ... Your implementation of your subclass
};
my_streambuf msb{ /* Parameters to your class's constructor */ }
std::istream i{&msb};
At this point, i is an ordinary input stream and does everything that any other input stream does. You can seek it. You can read from it.
Of course, the hard part is implementing your custom subclass of std::streambuf. This is not something that can be fully described in one or two paragraphs on stackoverflow.com. You should read std::streambuf's documentation, specifically the descriptions of its virtual methods. Your custom subclass will need to reimplement std::streambuf's virtual methods and make them work with your buffer. It's likely you will not need to reimplement all the virtual methods. For some of them their default implementation will be sufficient. Some of them won't be needed, for what you end up doing with std::istream.
You will have to determine, based on you specific needs to what extent you need to reimplement which std::streambuf's virtual methods, and how.
Of course, another, easy alternative is to use your buffer to construct a std::string, and then using it to construct a std::istringstream, and call it a day. Of course, that'll be somewhat wasteful and require effectively doubling the memory used for the data, with a second copy that's owned by a throw-away std::string, and copying it. If this is a small amount of data that's probably fine, but if your buffer is very big that may not be practical, and a custom std::streambuf subclass that uses the buffer directly is your only option.
Like the other answer mentioned, you can use an std::stringstream if you don't want to go the std::streambuf route:
std::stringstream ss;
std::copy(png_data.begin(), png_data.end(), std::ostreambuf_iterator<uint32_t>(ss));
Then you just use it like an input stream.

What is the standard output buffer called?

When I write a filebuf, everything is ok.
I'd like to know what is called a buffer for standard output.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
filebuf m;
m.open("/home/patryk/untitled6/text.txt", ios::out);
ostream out(&m);
out<<"to ja";
}
I don't want use e.g cout.rdbuf.
Only as above
The name of the output stream
#include <iostream>
using namespace std;
int main()
{
ostream out(cout.rdbuf());
out<<"to ja";
}
It is an implementation defined type derived from std::streambuf Here is what a popular C++ reference says:
The global objects std::cout and std::wcout control output to a stream buffer of implementation-defined type (derived from std::streambuf), associated with the standard C output stream stdout.
This means you can only realistically access the instance currently inside std::coutusing std::cout.rdbuf() - unless your compiler vendor provides non-standard access to its relevant internals.
For example, GCC provides stdio_filebuf, an instance of which could be "wrapped around" the standard output file descriptor.
In both examples, there is no need to use std::ostream the way you are.
In the first example, use std::ofstream instead of std::filebuf:
ofstream out("/home/patryk/untitled6/text.txt");
out << "to ja";
In the second example, std::cout is already a std::ostream so just write to it directly:
cout << "to ja";
In both cases, this abstracts away how the actual buffers are implemented. Just focus on the higher level stream interface by itself. The buffers used are just implementation details.

Is it possible to pass the stringbuf's streambuf direct to the filebuf?

I'm working on function that manipulate a stringbuf and I need to keep this in a file.
If I could pass the stringbuf directly to ofstream's filebuf that could be a huge advantage.
I know that both use streambuf object than can I somehow replace the filebuf's streambuf to my stringbuf's stream?
Take a look to the code below to better understand the idea:
#include <fstream>
#include <sstream>
void printit(std::stringbuf &MyBb) {
std::ofstream fFile("newfile.txt");
fFile.rdbuf(MyBb.rdbuf()); //MyBb doesn't have this member function
//How can I give to fFile the streambuf
//from my stringbuf?
}
int main() {
std::stringbuf MyB;
MyB.sputn("First sentence\n",15);
printit(MyB);
return 0;
}
You just need to do like you were writing a string to it and use your function. Use fFile << MyPb.rdBuff(); That should probably work

std::cout, ostream and other kinds of getting output stream

In my project (Unreal Engine 4) I don't have an output stream - instead of this I can communicate via UE_LOG function, which works pretty much similar to printf(). The problem is that I just made a .dll library (without Unreal includes) which I want to communicate through the iostream. My idea is - inside .dll library I use standard cout to write messages into ostream, I use all of it in Unreal Engine functions, where I grab ostream in form of string and output it into UE_LOG function.
Problem is I always treated std::cout as a part of magic, without thinking what is really inside (I am pretty sure most of us did). How I can handle this? Easy ways won't work (like grabbing stringstream and outputing it into UE_LOG).
My idea is - inside .dll library I use standard cout to write messages into ostream
You actually can replace the output buffer used with std::cout with your own implementation. Use the std::ostream::rdbuf() function to do so (example from the reference docs):
#include <iostream>
#include <sstream>
int main()
{
std::ostringstream local;
auto cout_buff = std::cout.rdbuf(); // save pointer to std::cout buffer
std::cout.rdbuf(local.rdbuf()); // substitute internal std::cout buffer with
// buffer of 'local' object
// now std::cout work with 'local' buffer
// you don't see this message
std::cout << "some message";
// go back to old buffer
std::cout.rdbuf(cout_buff);
// you will see this message
std::cout << "back to default buffer\n";
// print 'local' content
std::cout << "local content: " << local.str() << "\n";
}
(in case my edit won't be positively reviewed)
From OP: Thanks to your hints I finally found how to solve my problem. Suppose I want to get stream from cout and send it to printf (because I think stdio library is superior to iostream). Here how I can do this:
#include <iostream>
#include <sstream>
#include <cstdio>
using namespace std;
class ssbuf : public stringbuf{
protected:
int sync(){
printf("My buffer: %s",this->str().c_str());
str("");
return this->stringbuf::sync();
}
};
int main(){
ssbuf *buf = new ssbuf();
cout.rdbuf(buf);
cout<<"This is out stream "<<"and you cant do anything about it"<<endl;
cout<<"(don't) "<<"Vote Trump"<<endl;
}
Code is very raw, but it does it's job. I made child class of buffer which has method sync() downcasting original virtual method sync(). Except this it works like usual buffer, just grabs all console-out stream - exactly what we wanted. The str("") inside is to clean the buffer - probably not outputted stream doesn't clean itself.
Great thanks for help! Big GRIN for you! :D

How to redirect std::cout to a UITextView?

I'm adding C++ code to an iOS application, and I would like to use a UITextView as a way to display what's going through std::cout. I don't want to modify the C++ code too much.
So far, I have defined a string stream named stdcout, in the scope of the C++ code I'm interested in capturing the output, and I'm updating the UITextView after the C++ block returns. This is a bit intrusive, as I need to do some manual text replacing, and it's error prone.
Is there a better way to do this ?
You can look at rdbuf().
If you care about performance/flexibility, you could write a custom stream buffer and implement the overflow members so that you get "automatic" "live" updating.
Here's a simple example relaying to a stringstream:
#include <sstream>
#include <iostream>
int main()
{
std::ostringstream oss;
auto saved = std::cout.rdbuf(oss.rdbuf());
std::cout << "hello world" << std::endl;
std::cout.rdbuf(saved);
return oss.str().length();
}
This program exits with exitcode '12' on my cygwin shell:
./test.exe; echo $?
12