Andrei Olar
Andrei Olar

Reputation: 2358

How to redirect program output to text file

I want to redirect the output of a program to a file. How can I do this? At the moment my file doesn't get created, I can only print the output to my console.

    int fd[2];
    int processId;
    int output;
    char filename[] = "output.txt";

    if((output = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR)) == -1){
        fprintf(stderr, "Unable to create/open file '%s'\n", filename);
        return 1;
    }

    if(pipe(fd) == -1){
        fprintf(stderr, "Error creating pipe\n");
        return 2;
    }

    if((processId = fork()) == -1){
        fprintf(stderr, "Error forking\n");
        return 3;
    }   

    if(processId == 0){
        int newFD = dup(STDOUT_FILENO);
        char newFileDescriptor[2];
        sprintf(newFileDescriptor, "%d", newFD);
        dup2(fd[1], output);
        close(fd[0]);
        execl("./pipetest", "pipetest", newFileDescriptor, NULL);
    }else{
        close(fd[1]);
        char c[10];
        int r = read(fd[0], c, sizeof(char) * 10);

        if(r > 0){
            fprintf(stderr, "PIPE INPUT = %s", c);
            fwrite(c, 1, sizeof(c), output);
        }
    }

Upvotes: 1

Views: 5854

Answers (4)

nsilent22
nsilent22

Reputation: 2863

Here's simples example how to do this:

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

int main(void) {
    int out = open("/tmp/output.txt", O_WRONLY | O_CREAT, 0644);
    if (out == -1) {
        perror("open:");
        return -1;
    }
    int r;
    r = close(1); /* this closes stdout */
    if (r != 0) {
        perror("close:");
        return -1;
    }
    r = dup2(out, 1); /* this duplicates your file descriptor to stdout */
    if (r == -1) {
        perror("dup2:");
        return -1;
    }
    printf("this should go to the output file\n");
    return 0;
}

Upvotes: 0

that other guy
that other guy

Reputation: 123680

A good start is not ignoring compiler warnings:

test.c: In function ‘main’:
test.c:42:13: warning: passing argument 4 of ‘fwrite’ makes pointer from integer without a cast [enabled by default]
             fwrite(c, 1, sizeof(c), output);
             ^
In file included from test.c:1:0:
/usr/include/stdio.h:715:15: note: expected ‘struct FILE * __restrict__’ but argument is of type ‘int’
 extern size_t fwrite (const void *__restrict __ptr, size_t __size,
               ^

int and FILE* are not interchangable. If you use open, write with write. If you use fopen, write with fwrite.

Additionally, you never modify stdout of your process. Instead you modify output, which doesn't make sense. Here are the minimum changes to your code to make it work:

#include <stdio.h>                                                                                                                                                                                                                                                                                                                                                                                                                       
#include <sys/types.h>                                                                                                                                                                                                                                                                                                                                                                                                                   
#include <sys/stat.h>                                                                                                                                                                                                                                                                                                                                                                                                                    
#include <fcntl.h>                                                                                                                                                                                                                                                                                                                                                                                                                       
#include <unistd.h>                                                                                                                                                                                                                                                                                                                                                                                                                      

int main() {                                                                                                                                                                                                                                                                                                                                                                                                                             
    int fd[2];                                                                                                                                                                                                                                                                                                                                                                                                                           
    int processId;                                                                                                                                                                                                                                                                                                                                                                                                                       
    int output;                                                                                                                                                                                                                                                                                                                                                                                                                          
    char filename[] = "output.txt";                                                                                                                                                                                                                                                                                                                                                                                                      

    if((output = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR)) == -1){                                                                                                                                                                                                                                                                                                                                                          
        fprintf(stderr, "Unable to create/open file '%s'\n", filename);                                                                                                                                                                                                                                                                                                                                                                  
        return 1;                                                                                                                                                                                                                                                                                                                                                                                                                        
    }                                                                                                                                                                                                                                                                                                                                                                                                                                    

    if(pipe(fd) == -1){                                                                                                                                                                                                                                                                                                                                                                                                                  
        fprintf(stderr, "Error creating pipe\n");                                                                                                                                                                                                                                                                                                                                                                                        
        return 2;                                                                                                                                                                                                                                                                                                                                                                                                                        
    }                                                                                                                                                                                                                                                                                                                                                                                                                                    

    if((processId = fork()) == -1){                                                                                                                                                                                                                                                                                                                                                                                                      
        fprintf(stderr, "Error forking\n");                                                                                                                                                                                                                                                                                                                                                                                              
        return 3;                                                                                                                                                                                                                                                                                                                                                                                                                        
    }                                                                                                                                                                                                                                                                                                                                                                                                                                    

    if(processId == 0){                                                                                                                                                                                                                                                                                                                                                                                                                  
        int newFD = dup(STDOUT_FILENO);                                                                                                                                                                                                                                                                                                                                                                                                  
        char newFileDescriptor[2];                                                                                                                                                                                                                                                                                                                                                                                                       
        sprintf(newFileDescriptor, "%d", newFD);                                                                                                                                                                                                                                                                                                                                                                                         
        dup2(fd[1], STDOUT_FILENO); // You want to modify STDOUT_FILENO                                                                                                                                                                                                                                                                                                                                                                  
        close(fd[0]);                                                                                                                                                                                                                                                                                                                                                                                                                    
        execl("/bin/echo", "echo", newFileDescriptor, NULL); // switched to echo                                                                                                                                                                                                                                                                                                                                                         
    }else{                                                                                                                                                                                                                                                                                                                                                                                                                               
        close(fd[1]);                                                                                                                                                                                                                                                                                                                                                                                                                    
        char c[10];                                                                                                                                                                                                                                                                                                                                                                                                                      
        int r = read(fd[0], c, sizeof(char) * 10);                                                                                                                                                                                                                                                                                                                                                                                       

        if(r > 0){                                                                                                                                                                                                                                                                                                                                                                                                                       
            fprintf(stderr, "PIPE INPUT = %s", c);                                                                                                                                                                                                                                                                                                                                                                                       
            write(output, c, r); // use write instead of fwrite                                                                                                                                                                                                                                                                                                                                                                          
        }                                                                                                                                                                                                                                                                                                                                                                                                                                
    }                                                                                                                                                                                                                                                                                                                                                                                                                                    
}                                                                                                                                                                                                                                                                                                                                                                                                                                        

Here's the result of running it:

$ gcc test.c -o test
$ ./test
PIPE INPUT = 6
$ cat output.txt 
6

Upvotes: 5

user4520
user4520

Reputation: 3457

You can use freopen, it's probably the simplest way:

if (!freopen("out.txt", "w", stdout))
{
    // failed to open the file stream, handle the error
}

You can then just use printf to write to that file. You can do the same with stderr, but that's probably a bad idea - by definition stderr is used to report errors, and from what I know the convention is to have it output to console.

Upvotes: 1

Pooya
Pooya

Reputation: 6136

The easiest way is to do this at the bash by calling:

./myprogram > output.txt

This will redirect all of the outputs to output.txt

Upvotes: 1

Related Questions