using std::freopen to redirect stderr c++ - c++

I want to redirect all stderr to a file, which is also being used by my logger for the entire time the application (game) is running.
The following redirects it away from the console, but it never appears in my file, and using fclose after the game loop is over doesn't actually do anything, where it normally should.
freopen(Logger::logFile.c_str(),"a",stderr);
Any help would be great on how to get stderr to output to the text file, in a game loop.

We might here be playing with undefined behavior... because you must not use freopen to redirect various things to the same file.
In the below example, depending on what file you close, you will write differently:
#include <stdio.h>
int main ()
{
freopen ("myfile.txt","w",stdout);
printf (" This sentence is redirected to a file.");
// fclose (stdout);
freopen ("myfile.txt","w",stderr);
fprintf (stderr, "This ERRORis redirected to a file.");
//fclose (stderr);
fclose (stdout);
return 0;
}
Here you write the error before the sentence:
This ERRORis redirected to a file.sentence is redirected to a file.
Not great. I suggest you let the OS do this redirection to same file work for you, e.g. in Unix / Linux:
./myprog.sh 2>&1

Related

fprintf function not working but it returns positive number

I'm using fprintf in the following way. Everything seems to be ok but fprintf doesn't print to my file at all!
fprintf(pFile, "%s\n", "print");
Something that is strange is that fprintf returns OK. it returns 6 in the above code, but not printing to file!
The file is created successfully but is empty.
changing it to printf is printing and OK too.
fprintf and the other stdio output functions are buffered, which means that the output is first stored in memory, and not actually printed until later. When printing to the screen using standard output, each new line flushes the buffer, so with printf you would see the output immediately, but when printing to a file the buffer won't be flushed until you have written (for example) 4096 bytes. You can add fflush(pFile); to flush the buffer, if you for some reason need the output to appear on the file quickly.
The buffer is also flushed when calling fclose, or closing the file implicitly by properly exiting the program, but if the program keeps running without closing the file, or if it crashes, you will need fflush to see the output on the file.

get failed output back

I'm trying to run a script and output the result in the console. It works, but there is a
small problem i'm facing right now. If the "script" file is writed/coded wrong i get as output something like:
syntax error, unexpected $undefined, expecting $end puts
which is very good that it tells me somehting is wrong with the code inside the script file, but in my code line:
printf("%s", path);
it dosent print that to me and i want it to print it so i can display it on the screen. Please help me out
fp = popen("our script...is here", "r");
if (fp == NULL)
/* Handle error */;
while (fgets(path, PATH_MAX, fp) != NULL)
printf("%s", path);
status = pclose(fp);
Ps: just to make it more clear i'm using xcode and dont mind the code in C or C++
By default fgets() reads only from stdout of the stream. To capture stderr, you can simply redirect it to stdout:
fp = popen("./script 2>&1", "r");
Now both the stdout and stderr will go stdout which your C code can read from.
Note that once you have redirected as above there's no way to differentiate stdout and stderr.
You have to care about the stderr - popen() handled only stdout:
Conversely, reading from a "popened" stream reads the command's standard output,
The shell error will be printed to stderr - which popen() does not handle.

How to listen to stderr in C/C++ for sending to callback?

How do I passively listen to stderr and obtain it as string for sending to callback? I have seen posts on reading stderr but I want to listen to it rather than actively reading it.
Background:
I have a cross-platform piece that uses 3rd party library (libcurl) which will output verbose info into stderr. This cross-platform piece is to be used by more than 1 non-cross-platform applications.
I would like to log these info, which I can do by providing FILE* to libcurl. But instead of doing that, I want to see if I can capture (passively listen to) the output in stderr as string, and send back to the calling main application via callback. This has the benefit of 1. main app can keep a single log using whatever logging tool it wants. 2. it will keep this piece cross-platform.
Doing this in a single process is a little tricky, but you can probably do it.
1: Using freopen() you can redirect your stderr to a named file. You can simultaneously open that file for reading on another handle. You might also need to call setvbuf() on stderr to turn off buffering on output to stderr so that you will be able to read it right away from the 2nd handle. Since it is being written to a file you can read it at anytime - when it is convenient. The unix function "select" is what you need if you want to be notified when the file changes. (see also fileno()).
2: More tricky would be to setup stderr as the write end of a pipe. Should be doable using dup3(), though this isn't exactly cross-platform (to non-unixy OS's). It would also require that a 2nd thread be reading from the pipe to prevent the writer from being blocked if they write very much.
Like:
FILE *stream = freopen("stderr.out", "w", stderr); // Added missing pointer
setvbuf(stream, 0, _IONBF, 0); // No Buffering
FILE *input = fopen("stderr.out", "r");
fprintf(stderr, "Output to stderr dude\n");
//fflush(stderr); // You can explicitly flush instead of setting no buffering.
char buffer[1024];
while (fgets(buffer, 512, input))
{
printf(">>>%s\n", buffer);
}

C++ Redirect Output

Is there a way to redirect c++ output inside the code?
The situation is this, I am using some external .cpp and .h files which use printf's to put warnings to console. I wish to redirect "only" these outputs (not mine) to a file "without" modifying their code.
So; in my program, I can redirect ouput to a file, and when I will put some output redirect again to default console, after that again to file, so on...
Is it possible?
You can use freopen() on stdout to redirect stdout to a file.
printf will print to file descriptor 1, you can close it and open a file, this will give you another fd, possibly 1 because its the lowest fd available, if not you weren't fast enough.
If you just close(1); and then int fd = open(file); fd should be 1 if none has opened something between the close and the open. At that point anyone outputting to fd number 1 will print to your file.
This is because the system should give you the lowest available file descriptor number so it'll give you 1 which is exactly where printf writes.
As #roe mentioned you might prefer to do a dup() over 1 first to get another fd number where you can print to stdout.

Writing ALL program output to a txt file in C++

I need to write all my program output to a text file. I believe it's done this way,
sOutFile << stdout;
where sOutFile is the ofstream object that creates the file like this:
sOutFile("CreateAFile.txt" ); // CreateAFile.txt is created.
When I insert the stdout into the sOutFile object, I get some code which seems to resemble octal [hexadecimal] code or an address of some kind in the text file that I created.
0x77c5fca0
But what's confusing to me is that in my program I use cout several times. Mostly just literal statement. If I'm not mistaken that is the program output.
If this code is an address, would it contain all of my output? Could I read it back in to the program and find out that way?
What can I do to get ALL of my program output written to a text file?
If your program already uses cout/printf and you want to send EVERYTHING you currently output to a file, you could simply redirect stdout to point to a file before your existing calls:
http://support.microsoft.com/kb/58667
Relevant Code:
freopen( "file.txt", "w", stdout );
cout << "hello file world\n"; // goes to file.txt
freopen("CON", "w", stdout);
printf("Hello again, console\n"); // redirected back to the console
Alternatively if you just want Some things to be printed to a file, you just want a regular file output stream: http://www.cplusplus.com/doc/tutorial/files.html
Relevant Code:
ofstream myfile;
myfile.open("file.txt");
myfile << "Hello file world.\n";
printf("Hello console.\n");
myfile.close();
EDIT to aggregate answers from John T and Brian Bondy:
Finally, if you're running it from the commandline, you can just redirect the output as everyone else mentioned by using the redirect operator ">" or append ">>":
myProg > stdout.txt 2> stderr.txt
This is a duplicate of: this question
You can redirect stdout, stderr and stdin using std::freopen.
From the above link:
/* freopen example: redirecting stdout */
#include <stdio.h>
int main ()
{
freopen ("myfile.txt","w",stdout);
printf ("This sentence is redirected to a file.");
fclose (stdout);
return 0;
}
You can also run your program via command prompt like so:
a.exe > stdout.txt 2> stderr.txt
If you want all output in a text file you don't need to code anything extra.
from the command line:
program > output.txt
If you only wish to redirect certain output you can use ostream as dirkgently suggested.
Then you cannot use std::cout anywhere else to print stuff from your program. Change std::cout to a std::ostream and then pass your file or std::cout as required.
sOutFile << stdout;
in C "stdout" is defined as a FILE* variable. It's just a pointer. Outputing it to a file just writes the value of the pointer, in your case: 0x77c5fca0 to the file.
If you want to direct your output to a file either write it the a file in the first place or redirect the output of your program to a file using the command line.