car*_*ten 7 c c++ io file-descriptor io-redirection
我想做的事
将stdout和stderr重定向到c ++中的一个或多个文件
为什么我需要它
我正在使用一个外部的,预编译的第三方库,它产生了大量的输出,我想将其重定向到日志文件以保持控制台清洁.
条件
兼容性不是问题,代码只能在Unix系统上运行.重定向不仅应该影响c ++风格的打印(std :: cout <<"hello world"<< std :: endl),还应该影响c风格的打印(printf("hello world \n")).
到目前为止我尝试过的
我一直在浏览stackoverflow半天,为有类似问题的人阅读多个答案.借助这些答案,我能够将以下代码组合在一起:
#include <stdio.h>
#include <iostream>
#include <fcntl.h>
#include "unistd.h"
const int stdoutfd(dup(fileno(stdout)));
int redirect_stdout(const char* fname){
fflush(stdout);
int newstdout = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
dup2(newstdout, fileno(stdout));
close(newstdout);
}
int restore_stdout(){
fflush(stdout);
dup2(stdoutfd, fileno(stdout));
close(stdoutfd);
return stdoutfd;
}
int main(){
redirect_stdout("/dev/null");
std::cout << "invisible 1" << std::endl;
restore_stdout();
std::cout << "visible 1" << std::endl;
redirect_stdout("/dev/null");
std::cout << "invisible 2" << std::endl;
restore_stdout();
std::cout << "visible 2" << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我期望看到的内容:
visible 1
visible 2
Run Code Online (Sandbox Code Playgroud)
我实际上看到了什么
visible 1
Run Code Online (Sandbox Code Playgroud)
也就是说,当第一次使用这种机制时,它可以工作 - 但如果再次使用,恢复输出将不起作用.有人可以指出我需要改变什么才能让机制经常无限地工作吗?
除了freopen()的afr0ck答案之外,我想说的是,在使用时我们应该小心。一旦像或这样的流通过分配新目标(此处为“output.txt”文件)重新打开,它总是保留在程序中,除非它已被显式更改。freopen()stdoutstdin
freopen("output.txt", "a", stdout);
Run Code Online (Sandbox Code Playgroud)
这里重新打开标准输出流stdout并分配“output.txt”文件。之后,每当我们使用-printf()或任何其他stdout流putchar()时,每个输出都会转到'output.txt'。要恢复默认行为(即在控制台/终端中打印输出),printf()我们putchar()可以使用以下代码行 -
freopen("/dev/tty", "w", stdout);freopen("CON", "w", stdout);请参阅下面的代码示例 -
#include <stdio.h>
int main() {
printf("No#1. This line goes to terminal/console\n");
freopen("output.txt", "a", stdout);
printf("No#2. This line goes to the \"output.txt\" file\n");
printf("No#3. This line aslo goes to the \"output.txt\" file\n");
freopen("/dev/tty", "w", stdout); /*for gcc, diffrent linux distro eg. - ubuntu*/
//freopen("CON", "w", stdout); /*Mingw C++; Windows*/
printf("No#4. This line again goes to terminal/console\n");
}
Run Code Online (Sandbox Code Playgroud)
此代码会在当前目录中生成一个“output.txt”文件,并且 No#2 和 No#3 将打印在“output.txt”文件中。
谢谢