redirecting output to a file in C
This is the result of my testing things out with dup2
The more subtle point is remembering fflush at the right times :) Otherwise, you'll get very surprising results.
Also, prefer fileno
instead of hardcoding 1
(stdout) 2
(stderr).
Redirecting stdin
was left as an exercise for the reader
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
int out = open("cout.log", O_RDWR|O_CREAT|O_APPEND, 0600);
if (-1 == out) { perror("opening cout.log"); return 255; }
int err = open("cerr.log", O_RDWR|O_CREAT|O_APPEND, 0600);
if (-1 == err) { perror("opening cerr.log"); return 255; }
int save_out = dup(fileno(stdout));
int save_err = dup(fileno(stderr));
if (-1 == dup2(out, fileno(stdout))) { perror("cannot redirect stdout"); return 255; }
if (-1 == dup2(err, fileno(stderr))) { perror("cannot redirect stderr"); return 255; }
puts("doing an ls or something now");
fflush(stdout); close(out);
fflush(stderr); close(err);
dup2(save_out, fileno(stdout));
dup2(save_err, fileno(stderr));
close(save_out);
close(save_err);
puts("back to normal output");
return 0;
}
How to redirect program output to text file
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
How to redirect output to a file in C?
Online, it says that
>
redirects command output to a file, and I'm not sure exactly what "command output" means.
"command output" refers to the stdout
(Standard Output) stream of the program.
Do note that some shell commands are not separate programs but are actually shell builtins, though they'll still support output redirection. On Windows, most shell commands (like dir
and del
) are built-ins whereas on Linux/BSD/etc most shell commands are separate programs (like ls
and mkdir
)
If your program calls puts( "foobar" );
then running ./name
from Bash will display "foobar" in your terminal emulator. But if you run ./name > file.txt
then the "foobar" text will be written to file.txt
and it will not be displayed in your terminal emulator.
Try it with the ls
command, for example: ls -al > files.txt
. This works on Windows too (dir /s > files.txt
).
I'm redirecting the output from my
name.c
file to theoutputFileName.ext
file. Does command output mean stdout?
Yes.
If so, which C keyword would I use to write information to the outputFileName.ext file from name.c as stdout?
You don't. This is a shell/OS feature and is not part of C.
Redirect stdout to a file
What your code essentially does is that you open a pipe, then fork the process and in the child process (in commented code) close stdout, duplicate the pipe to stdout and execute and ls command, and then (in non-commented code) write 4 bytes to the pipe. In the parent process, you read data from the pipe and wait for the completion of the child process.
Now you want to redirect stdout to a file. You can do that by opening a file using the open() system call and then duplicating that file descriptor to stdout. Something like (I haven't tested this so beware of bugs in the code):
int filefd = open("foo.txt", O_WRONLY|O_CREAT, 0666);
if (!fork()) {
close(1);//Close stdout
dup(filefd);
execlp("ls", "ls", NULL);
} else {
close(filefd);
wait(NULL);
}
return 0;
However, you can also use the freopen as suggested by the other answer.
However, I have several concerns of your code and of my modified code:
The pipe() and open() system calls can fail. You should always check for system call failure.
The fork() system call can fail. Ditto.
dup2() can be used instead of dup(); otherwise the code will fail if stdin is not open as it duplicates to the first available file descriptor.
The execlp() system call can fail. Ditto.
I think wait() can be interrupted by a signal (EINTR). It's recommended to wrap it around a wrapper that retries the system call if it's aborted by a signal (errno == EINTR).
Redirect output from function to File in C
using freopen should help you.
freopen("temp.txt", "a+", stdout);
After reopening the stdout with freopen() all output statement printf, putchar
are redirected to file temp.txt
. So after that any printf()
statement will redirect it's output to the temp.txt
file.
reference:
https://linux.die.net/man/3/freopen
Redirect C output to a txt file
The user input is stdin
but you are redirecting only stdout
to file. Hence you will see in the output.txt
only what your program prints to stdout
. If you want to print entered values, you have to print them after scanf
.
In the example below, you should see also input values in your output.txt
printf("Enter float1: ");
scanf("%f", &float1);
printf("%f\n", float1);
Redirect output to txt file on multiple lines
The only line break you output is at the very end of your code. If you want line breaks in the output, output them wherever you want them, just as you did in the last line of code.
Redirect standard output to file and re-establish the standard output with function
I finally got the correct answer, so here is how to temporarily redirects the standard output to a file name "file", then executes the function f, then re-establishes the original standard output:
void redirect_stdout (void (*f)(void), char *file)
{
int fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0644);
int savefd = dup(1);
dup2(fd, 1);
f();
dup2(savefd, 1);
close(fd);
close(savefd);
}
Redirecting output to file then back to console in C++
Probably what you are looking for is rdbuf() as mentioned by doomista in the comments.
Here is a way to redirect Output.
#include <iostream>
#include <fstream>
int main()
{
/** backup cout buffer and redirect to out.txt **/
std::ofstream out("out.txt");
auto *coutbuf = std::cout.rdbuf();
std::cout.rdbuf(out.rdbuf());
std::cout << "This will be redirected to file out.txt" << std::endl;
/** reset cout buffer **/
std::cout.rdbuf(coutbuf);
std::cout << "This will be printed on console" << std::endl;
return 0;
}
Related Topics
What Character Sequence Should I Not Allow in a Filename
What's the Practical Limit on the Size of Single Packet Transmitted Over Domain Socket
What Does "|" Mean in a Terminal Command Line
How to Give Highest Priority to Ethernet Interrupt in Linux
.Bashrc Not Read When Shell Script Is Invoked from Desktop Shortcut
Executing Script on Receiving Incoming Connection with Xinetd
How to Check Fips 140-2 Support in Openssl
Loading Linux Text File into Excel Using Vba
Is /Dev/Random Considered Truly Random
Linux Combine Two Files by Column
Perf Stat Does Not Count Memory-Loads But Counts Memory-Stores