How to capture stdout temporarily?

  • Thread starter Santtu Nyrhinen
  • Start date
S

Santtu Nyrhinen

Hi,

Let say that I have a function like
void writeHello() {
printf("Hello");
}

Now I need to make an automated test fot that function.
The test function returns 1 for successful and 0 for unsuccessful test.
int Test_writeHello() {
...
writeHello();
...
}

Test funtion is called from test driver that reports to stdout how it went.
E.g. "Test case 10/20 OK Test_writeHello()"
I can redirect stdout to a file (freopen("file","w",stdout)) and then check
if the function works but how can I restore stdout back to the screen?

- Santtu
 
S

SM Ryan

# Hi,
#
# Let say that I have a function like
# void writeHello() {
# printf("Hello");
# }
#
# Now I need to make an automated test fot that function.
# The test function returns 1 for successful and 0 for unsuccessful test.
# int Test_writeHello() {
# ...
# writeHello();
# ...
# }
#
# Test funtion is called from test driver that reports to stdout how it went.
# E.g. "Test case 10/20 OK Test_writeHello()"
# I can redirect stdout to a file (freopen("file","w",stdout)) and then check
# if the function works but how can I restore stdout back to the screen?

If you're using Unix, it might be easier to fork and redirect output
in the child process only.
 
V

Vladimir Oka

Santtu said:
Hi,

Let say that I have a function like
void writeHello() {
printf("Hello");
}

Now I need to make an automated test fot that function.
The test function returns 1 for successful and 0 for unsuccessful test.
int Test_writeHello() {
...
writeHello();
...
}

Test funtion is called from test driver that reports to stdout how it went.
E.g. "Test case 10/20 OK Test_writeHello()"
I can redirect stdout to a file (freopen("file","w",stdout)) and then check
if the function works but how can I restore stdout back to the screen?

Have you considered using `stderr` for the test function. Most OSes can
redirect `stdout` and `stderr` to separate files/screens.
 
P

pemo

Santtu said:
Hi,

Let say that I have a function like
void writeHello() {
printf("Hello");
}

Now I need to make an automated test fot that function.
The test function returns 1 for successful and 0 for unsuccessful
test. int Test_writeHello() {
...
writeHello();
...
}

Test funtion is called from test driver that reports to stdout how it
went. E.g. "Test case 10/20 OK Test_writeHello()"
I can redirect stdout to a file (freopen("file","w",stdout)) and then
check if the function works but how can I restore stdout back to the
screen?

On XP and using gcc, the following works

freopen("CON:","w",stdout);

If you're on Linux et al, maybe you or someone else could try the following?

freopen("/dev/tty", "w",stdout);
 
R

rageratwork

pemo said:
On XP and using gcc, the following works

freopen("CON:","w",stdout);

If you're on Linux et al, maybe you or someone else could try the following?

freopen("/dev/tty", "w",stdout);

This works for me (your results may vary):
#include <stdio.h>

int main (int argc, char* argv[])
{
freopen ("test.txt", "w", stdout);
printf ("hello file!\n");
freopen ("/dev/tty", "w", stdout);
printf ("hello world!\n");
return 0;
}
 
C

Chris Torek

This works for me (your results may vary):
#include <stdio.h>

int main (int argc, char* argv[])
{
freopen ("test.txt", "w", stdout);
printf ("hello file!\n");
freopen ("/dev/tty", "w", stdout);
printf ("hello world!\n");
return 0;
}

This does not work for me. Here is what happened when I ran it:

% ./rageratwork > output
hello world!
% cat test.txt
hello file!
% cat output
%

The "captured" file ("test.txt") worked OK but the "output" file
was empty, and the output that *should* have been there appeared
on my virtual console.

(There *is* a way to make it "work" on a Unix-like system, but this
is off-topic here. Hint: ask about dup2() in comp.unix.programmer.
Arguably the best fix is to rewrite the code in question to take
a "FILE *" parameter, rather than assuming all its output is to go
to stdout. This can be done in completely portable C code, instead
of using system-specific hacks that have to be rewritten every time
you move to another system.)
 
R

rageratwork

Chris said:
This works for me (your results may vary):
#include <stdio.h>

int main (int argc, char* argv[])
{
freopen ("test.txt", "w", stdout);
printf ("hello file!\n");
freopen ("/dev/tty", "w", stdout);
printf ("hello world!\n");
return 0;
}

This does not work for me. Here is what happened when I ran it:

% ./rageratwork > output
hello world!
% cat test.txt
hello file!
% cat output
%

The "captured" file ("test.txt") worked OK but the "output" file
was empty, and the output that *should* have been there appeared
on my virtual console.

(There *is* a way to make it "work" on a Unix-like system, but this
is off-topic here. Hint: ask about dup2() in comp.unix.programmer.
Arguably the best fix is to rewrite the code in question to take
a "FILE *" parameter, rather than assuming all its output is to go
to stdout. This can be done in completely portable C code, instead
of using system-specific hacks that have to be rewritten every time
you move to another system.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.

I'd have to say the stdout you were redirecting to the output file was
closed at the first freopen hence, no ouput. If you put a printf before
the first freopen obviously you will see it in the redirected output
file.

Try this once:
#include <stdio.h>

int main (int argc, char* argv[])
{
FILE* f;

printf ("hello stdout!\n"); // stdout

f = fopen("/dev/stdout", "a");
fprintf (f, "hello /dev/stdout!\n"); // also stdout

freopen ("test.txt", "w", stdout);
printf ("hello file!\n"); // to the file

fprintf (f, "hello /dev/stdout!\n"); // still goes to the
redirected file

freopen ("/dev/tty", "w", stdout);
printf ("hello world!\n"); // back to the terminal

fprintf (f, "hello /dev/stdout! %d\n", fileno(f)); // still
goes to the redirected file
fclose (f);
return 0;
}

[rager]$ ./test > output
hello world!
[rager]$ cat test.txt
hello file!
[rager]$ cat output
hello stdout!
hello /dev/stdout!
hello /dev/stdout!
hello /dev/stdout! 3

Of course I completely agree that your portable C is the best solution
and the way I've always aproached this type of situation. Just thought
it was an interresting exercise...

Dave.
 
P

pemo

Chris said:
This works for me (your results may vary):
#include <stdio.h>

int main (int argc, char* argv[])
{
freopen ("test.txt", "w", stdout);
printf ("hello file!\n");
freopen ("/dev/tty", "w", stdout);
printf ("hello world!\n");
return 0;
}

This does not work for me. Here is what happened when I ran it:

% ./rageratwork > output
hello world!
% cat test.txt
hello file!
% cat output
%

The "captured" file ("test.txt") worked OK but the "output" file
was empty, and the output that *should* have been there appeared
on my virtual console.

(There *is* a way to make it "work" on a Unix-like system, but this
is off-topic here. Hint: ask about dup2() in comp.unix.programmer.
Arguably the best fix is to rewrite the code in question to take
a "FILE *" parameter, rather than assuming all its output is to go
to stdout. This can be done in completely portable C code, instead
of using system-specific hacks that have to be rewritten every time
you move to another system.)
--

Of course I completely agree that your portable C is the best solution
and the way I've always aproached this type of situation. Just thought
it was an interresting exercise...

Portable - what, where - in the **ux world only if you mean dup2 I believe?
 
R

rageratwork

pemo said:
Chris Torek wrote:
[snip][snip]
Of course I completely agree that your portable C is the best solution
and the way I've always aproached this type of situation. Just thought
it was an interresting exercise...

Portable - what, where - in the **ux world only if you mean dup2 I believe?

I believe Chris's solution is quite portable and has nothing to do with
duping any file descriptors. Pass in stdout or any other open file as a
parameter depending where you want the output to go.

Dave.
 
P

pemo

pemo said:
Chris Torek wrote:
[snip]
Arguably the best fix is to rewrite the code in question to take
a "FILE *" parameter, rather than assuming all its output is to go
to stdout. This can be done in completely portable C code, instead
of using system-specific hacks that have to be rewritten every time
you move to another system.)
[snip]
Of course I completely agree that your portable C is the best
solution and the way I've always aproached this type of situation.
Just thought it was an interresting exercise...

Portable - what, where - in the **ux world only if you mean dup2 I
believe?

I believe Chris's solution is quite portable and has nothing to do
with duping any file descriptors. Pass in stdout or any other open
file as a parameter depending where you want the output to go.

True - sorry, too quick off the mark!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top