5

Is there a way to modify the printf in order to output string on a file rather than to the console?

I tried looking up something on the Internet and found calls like dup, dup2 and fflush that might be associated with this.

EDIT:

Maybe I wasn't clear.. the thing is that this was in a C exam question.. the question is as follows:

Explain how a program that normally output strings to screen (using printf()) can be made to output string to a file, without changing any code in the mentioned program.

3
  • If you explain why you want to do this slighly bizarre thing, answers will generally be better. Commented Jun 8, 2012 at 10:43
  • 3
    How about fprintf? Or using shell redirection (./myprogram > some_file)? Commented Jun 8, 2012 at 10:43
  • @JoachimPileborg... thanks for your answer.. i will explore further the shell redirection option .. Commented Jun 8, 2012 at 11:01

6 Answers 6

12

If you do not have liberty to modify the source code that does printing, you can use freopen on stdout to redirect to a file:

stdout = freopen("my_log.txt", "w", stdout);

This borders on a hack, however, because command-line redirects will stop working as expected. If you do have access to the code that does printing, using fprintf is preferred.

You can also switch your stdout temporarily for a function call, and then put it back:

FILE *saved = stdout;
stdout = fopen("log.txt", "a");
call_function_that_prints_to_stdout();
fclose(stdout);
stdout = saved;
Sign up to request clarification or add additional context in comments.

3 Comments

so in this way the stdout is overwritten and will output to a file rather than to the console..?
also, how do you then make printf print to console again ?
@user1317277 Yes, once you freopen your stdout, the output goes to the file. You cannot go back after freopen, but you can store the old stdout and put it back the way I explained in the edit.
6

This is usually done with I/O-redirection (... >file).

Check this little program:

#include <stdio.h>
#include <unistd.h>

int main (int argc, char *argv[]) {
    if (isatty (fileno (stdout)))
        fprintf (stderr, "output goes to terminal\n");
    else
        fprintf (stderr, "output goes to file\n");

    return 0;
}

ottj@NBL3-AEY55:~ $ ./x
output goes to terminal
ottj@NBL3-AEY55:~ $ ./x >yy
output goes to file

Comments

3

The other answers don't cope with the problem of not changing any code.

So, depending on the environment, the only thing that is left is stdout redirection when calling the program.

./program > target_file

Comments

2

The lecturer was consulted and this was the correct solution provided (by the lecturer himself):

int main {
    int newFile = open(desiredFilePath, O_WRONLY)
    if ((fork())==0) {
        dup2(newFile,stdout) // Explained below
        close newFile
        Set stdout as CLOSE_ON_EXEC false
        exec the user program
    }
    else{
        Wait for child
    }
    return 0
}

The logic behind dup2: here stdout is set as a copy of newFile, meaning that FD 0 is now actually the user required file and not the console. This is because the default behavior of dup 2 is to close the second parameter’s filedescriptor and assign it to the first parameter.

Comments

1

Use either sprintf to write to a string, then to a file, or fprintf directly.

http://linux.die.net/man/3/fprintf

2 Comments

snprintf is almost always a better choice than sprintf to avoid buffer overflows.
@DelanAzabani I agree. Just wanted to keep things simple.
0

Because file use buffers, just use fflush(STDOUT_FILENO) after printf

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.