Redirecting stderr to stdout using string stream - c++

I have a code like this
int main()
{
std::stringstream oss;
std::cerr.rdbuf( oss.rdbuf() );
std::cerr << "this goes to cerr";
std::cout << "[" << oss.str() << "]";
}
But i get the output of the program as
[this goes to cerr]Segmentation fault
How does the program segfault?

This is because you do not restore the buffer of cerr before your program exits. Do it like this:
#include <iostream>
#include <sstream>
int main()
{
std::stringstream oss;
std::streambuf* old = std::cerr.rdbuf( oss.rdbuf() );
std::cerr << "this goes to cerr";
std::cout << "[" << oss.str() << "]";
std::cerr.rdbuf(old);
}
See this answer of mine for a solution that is exception safe.

The other answer correctly address the how does this program segfault part of your question. However, I feel that the real question Redirecting stderr to stdout using string stream.. deserves a better answer:
You may simplify the whole shebang and make it scale and perform a infitely better better by just aliasing cerr to cout:
#include <iostream>
int main()
{
std::cerr.rdbuf(std::cout.rdbuf());
std::cerr << "this goes to cerr";
}
If you really want to be explicit:
std::cerr.copyfmt(std::cout);
std::cerr.clear(std::cout.rdstate());
std::cerr.rdbuf(std::cout.rdbuf());
You can verify that the text is actually received on stdout when run

Related

C++ programs not working correctly in VS Code [duplicate]

#include <bits/stdc++.h>
using namespace std;
void scan_a_line_indefinitely()
{
// scan line indefinitely
string input_line;
while(getline(cin,input_line))
{
cout << input_line ; **// doesn't print if i use this line**
//cout << input_line << endl; **// if i use this line, it works fine**
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
scan_a_line_indefinitely();
return 0;
}
someone please help me understand the problem with this code.
i think the problem is with cout.tie() and cout.tie(), when i remove these, program works fine.
std::cout will flush under these conditions:
An input-stream which is tied to std::cout tries to read input.
You removed the ties.
iostreams are synchronized with stdio, thus effectively unbuffered.
You disabled the synchronization.
The buffer is full.
That takes a bit longer.
The program ends normally.
That comes too late for you.
There is a manual flush (stream.flush() which is called when streaming std::flush; stream << std::endl is equivalent to stream << stream.widen('\n') << std::flush).
You have none of those.
So, fix any of them and you will see your output earlier.
If only iostreams are used you can add a manual flush to the output :
std::cout.flush();
Or
std::cout << /* the output */<< std::flush;
Also:
std::cout << std::endl is equivalent to std::cout << '\n' << std::flush

When i use cout.tie(NULL), program doesn't print anything for my code, but if i print endl, program works fine

#include <bits/stdc++.h>
using namespace std;
void scan_a_line_indefinitely()
{
// scan line indefinitely
string input_line;
while(getline(cin,input_line))
{
cout << input_line ; **// doesn't print if i use this line**
//cout << input_line << endl; **// if i use this line, it works fine**
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
scan_a_line_indefinitely();
return 0;
}
someone please help me understand the problem with this code.
i think the problem is with cout.tie() and cout.tie(), when i remove these, program works fine.
std::cout will flush under these conditions:
An input-stream which is tied to std::cout tries to read input.
You removed the ties.
iostreams are synchronized with stdio, thus effectively unbuffered.
You disabled the synchronization.
The buffer is full.
That takes a bit longer.
The program ends normally.
That comes too late for you.
There is a manual flush (stream.flush() which is called when streaming std::flush; stream << std::endl is equivalent to stream << stream.widen('\n') << std::flush).
You have none of those.
So, fix any of them and you will see your output earlier.
If only iostreams are used you can add a manual flush to the output :
std::cout.flush();
Or
std::cout << /* the output */<< std::flush;
Also:
std::cout << std::endl is equivalent to std::cout << '\n' << std::flush

fstream test program crashes for some reason

I have been playing around with the fstream class in C++ to see if I am able to write some data to a text file(.txt). According to what I know, If the program tries to write to a file that does not exist then it would automatically create that file, am I wrong? This program is very simple and does not give me any compiler errors which means it builds fine. However for some reason it crashes when I run it.
Here is my code:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <fstream>
std::fstream* myFile;
int main()
{
int age = 15;
std::string myName = "Javier Martinez";
std::string friendsName = "David Lyn";
//Backslash is a special character, use double backslash or forward slash instead.
myFile->open("C:/Users/NIKE/Desktop/data.txt");
if (myFile->fail())
{
std::cerr << "File was unable to be opened.";
}
*myFile << age << "\n";
*myFile << myName << "\n";
*myFile << friendsName << "\n";
myFile->close();
std::cout << "File was successfully written to with the data";
return 0;
}
Any help is appreciated. Thank you in advance.
NOTE: I am using the GNU GCC compiler with Code::Blocks IDE
myFile is uninitialized. Check it.( Allocate memory) or simply use fstream.
Your problem stems from the line:
std::fstream* myFile;
You only declared a pointer to a stream object, which is initialized to nullptr by reason of it being in the global scope. The fact that you tried accessing a non-existent object (invalid) through it, you invoked what is known as Undefined Behavior.
You do not need to allocate stream objects on the heap, rather, do:
std::fstream myFile;
On a side Note: Check your program control flow:
if (!myFile)
{
std::cerr << "File was unable to be opened.";
}
else{
myFile << age << "\n";
myFile << myName << "\n";
myFile << friendsName << "\n";
}

C++ (pre C++11) fstream initialized by sstream

I am trying to open other process stdin and write to it, using C++, no dup() and other C tricks. But unfortunately, fstream constructor taking string seems to be available only from C++11 ( source:http://www.cplusplus.com/reference/fstream/fstream/fstream/ )
#include <iostream>
#include <fstream>
#include <sstream>
//using namespace std;
int main()
{
pid_t pid = fork();
if (pid == 0)
{
// std::cout << "child:" << i << std::endl;
std::string line;
std::cin.sync();
std::cout << "child got message:" << std::endl;
while ( std::getline(std::cin, line) )
{
std::cout << line << std::endl;
}
std::cout << "child done receiving" << std::endl;
}
else{
//std::cout << "parent"<<std::endl;
std::ifstream file("stdin", std::ios::in);
if(file.is_open())
{
std::string tmp, str;
std::stringstream pidstr;
pidstr << "/proc/" << pid << "/fd/0";
while ( std::getline(file, tmp) )
str += tmp + "\n";
std::fstream other( (pidstr.str().c_str()), std::ios::out);
other << str ;
}
}
return 0;
}
I have four questions:
Is "pidstr.str().c_str()" most C++ way to do it? Looks ugly to me.
Is that proper C++ way or maybe there are better alternatives?
Since, as far as I know, getline() is blocking, can I ommit cin.sync(), expecting child to wait for input in while ?
Why do I need to press enter twice, (regardless if i have getchar in child commented out or not(!))
Thanks for understanding.
EDIT: This compiles, and produces desired output, using Code:Blocks, Linux 13.04
EDIT2: No, apparently this does NOT produce desired output. I've added some changes: parent waits for child to exit (not important here).
But also changed this (in child) :
while ( std::getline(std::cin, line) )
{
std::cout << line << std::endl;
}
std::cout << "child done" << std::endl;
to this :
std::getline(std::cin, line);
int lines; // this is single line sent as first from parent, containing int
std::istringstream toint(line);
toint >> lines;
std::cout << "how much lines should it read:" << lines << std::endl;
And it appears that child will wait for anything on stdin, then prints out that what was sent from parent. Really, sometimes I wonder how should i consider C++ as better than plain C :/

Redirect some output to command prompt, and some to file?

I'm trying to redirect some of the standard output to a text file, and some other to the command prompt.
I'm currently outputting all of it to a file, but I'd like to output some to the command prompt, so I can know at least (get some hits), on what's been recorded (since it takes like 10 minutes to run this code)
This is what I'm doing;
FILE *stream ;
std::stringstream ss;
ss << "K_file.txt";
if((stream = freopen(ss.str().c_str(), "w", stdout)) == NULL)
exit(-1);
std::cout<<"blah blah blah...";
Edit based on comment;
'some' is part of the code where I would like to explicitly specify, example;
for(int i = 0; i<1000; i++)
{
std::cout<<"I would like this to go to the file - since it's detailed";
}
std::cout<<"loop finished - I would like this to go to the command prompt";
This might not be the best example but I hope you get the point.
You could "abuse" standard output and standard error stream for that. For example:
#include <iostream>
void main() {
std::cout << "standard output";
std::cerr << "standard error";
}
Now, if you redirect just the standard error to file...
your_program.exe 2> file.txt
...you'll get "standard output" in console window and "standard error" in file.txt.
(NOTE: This is Windows redirection syntax - I'm sure you'll have no trouble doing redirection on other OSes if you need to.)
I think this might help:
#include <fstream>
#include <iostream>
class stream_redirector {
public:
stream_redirector(std::ostream& dst, std::ostream& src)
: src(src), sbuf(src.rdbuf())
{
src.rdbuf(dst.rdbuf());
}
~stream_redirector() {
src.rdbuf(sbuf);
}
private:
std::ostream& src;
std::streambuf* const sbuf;
};
int main() {
std::ofstream log("log.txt");
std::cout << "Written to console." << std::endl;
{
// We redirect std::cout to log.
stream_redirector redirect(log, std::cout);
std::cout << "Written to log file" << std::endl;
// When this scope ends, the destructor will undo the redirection.
}
std::cout << "Also written to console." << std::endl;
}