英文:
Print in terminal after`freopen("file.txt", "wb", stdout);` (or similar solution to preserve a printing function)
问题
I want to store the printed output of a function with freopen("file.txt", "wb", stdout);
(or another solution, but the function matrix_output_printf()
should remain untouched.
However, I want to be able to further print something after having closed fclose(stdout);
as shown below but the hello
of printf("hello");
does not appear in the terminal. Is it possible to print "hello" in another way (on a MacOS system).
/*
* main.c
* https://stackoverflow.com/questions/75349098/stream-the-output-of-a-void-function-using-printf/75352112#75352112
*/
#include <stdio.h>
#include <stdlib.h>
void matrix_output();
void matrix_output_printf(){
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
printf("%d\t", i+j);
}
printf("\n");
}
}
int main ()
{
freopen("file.txt", "wb", stdout);
matrix_output_printf();
fclose(stdout);
printf("hello");
return 0;
}
Edit
The code provided in the answer is not working on my MacOS computer ( 'io.h' file not found
). Is there another solution portable for UNIX-like systems?
英文:
I want to store the printed output of a function with freopen("file.txt", "wb", stdout);
(or another solution, but the function matrix_output_printf()
should remained untouched.
However, I want to be able to further print something after having closed fclose(stdout);
as shown below but the hello
of printf("hello");
does not appear in terminal. Is it possible print hello in another way (on a MacOS system).
/*
* main.c
* https://stackoverflow.com/questions/75349098/stream-the-output-of-a-void-function-using-printf/75352112#75352112
*/
#include <stdio.h>
#include <stdlib.h>
void matrix_output();
void matrix_output_printf(){
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
printf("%d\t", i+j);
}
printf("\n");
}
}
int main ()
{
freopen("file.txt", "wb", stdout);
matrix_output_printf();
fclose(stdout);
printf("hello");
return 0;
}
Edit
The code provided in the answer is not working on my MacOS computer ( 'io.h' file not found
). Is there another solution portable for UNIX like systems?
答案1
得分: 1
以下是您代码的中文翻译部分:
已在我的Windows计算机上测试并验证:
#include <stdio.h>
#include <stdlib.h>
#include <io.h>;
void matrix_output_printf() {
for( int i = 0; i < 3; i++ ) {
for( int j = 0; j < 3; j++ )
printf( "%d\t", i+j );
printf( "\n" );
}
}
int main( void ) {
int saved = _dup( fileno( stdout ) );
freopen( "file.txt", "w", stdout );
matrix_output_printf();
fclose( stdout );
_dup2( saved, 1 );
printf( "hello\n" );
return 0;
}
英文:
Tried and tested on my Windows box:
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
void matrix_output_printf() {
for( int i = 0; i < 3; i++ ) {
for( int j = 0; j < 3; j++ )
printf( "%d\t", i+j );
printf( "\n" );
}
}
int main( void ) {
int saved = _dup( fileno( stdout ) );
freopen( "file.txt", "w", stdout );
matrix_output_printf();
fclose( stdout );
_dup2( saved, 1 );
printf( "hello\n" );
return 0;
}
答案2
得分: 0
If stdout
was originally tied to the console, you can reopen the stream to /dev/tty
:
#include <stdio.h>;
void matrix_output_printf(void) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%d\t", i + j);
}
printf("\n");
}
}
int main() {
freopen("file.txt", "w", stdout);
matrix_output_printf();
freopen("/dev/tty", "w", stdout);
printf("hello");
return 0;
}
This should work on most unix systems, such as macOS, but if stdout
was redirected to another file or device, reopening it with freopen
won't work. You could try and duplicate the system handle with dup()
and use fdopen()
to open a standard stream after closing stdout
, but there is no guarantee that the stream returned by fdopen
will be the same as stdout
.
Using freopen
for your purpose is a hack. A much better approach is to rewrite matrix_output_printf
to take a FILE *
argument for the output stream, or a const char *filename
for the name of the file to produce:
void matrix_output_printf(const char *filename) {
FILE *fp = stdout;
if (filename) {
fp = fopen(filename, "w");
if (fp == NULL) {
/* handle error */
return;
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
fprintf(fp, "%d\t", i + j);
}
fprintf(fp, "\n");
}
if (filename)
fclose(fp);
}
英文:
If stdout
was originally tied to the console, you can reopen the stream to /dev/tty
:
#include <stdio.h>
void matrix_output_printf(void) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%d\t", i + j);
}
printf("\n");
}
}
int main() {
freopen("file.txt", "w", stdout);
matrix_output_printf();
freopen("/dev/tty", "w", stdout);
printf("hello");
return 0;
}
This should work on most unix systems, such as macOS, but if stdout
was redirected to another file or device, reopening it with freopen
won't work. You could try and duplicate the system handle with dup()
and use fdopen()
to open a standard stream after closing stdout
, but there is no guarantee that the stream returned by fdopen
will be the same as stdout
.
Using freopen
for your purpose is a hack. A much better approach is to rewrite matrix_output_printf
to take a FILE *
argument for the output stream, or a const char *filename
for the name of the file to produce:
void matrix_output_printf(const char *filename) {
FILE *fp = stdout;
if (filename) {
fp = fopen(filename, "w");
if (fp == NULL) {
/* handle error */
return;
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
fprintf(fp, "%d\t", i + j);
}
fprintf(fp, "\n");
}
if (filename)
fclose(fp);
}
答案3
得分: 0
另一个选项:
- 刷新流
- 在调用该函数之前,复制
stdout
的文件描述符,将文件描述符复制到所需文件的流的原始文件描述符值 - 调用函数
- 恢复原始的
stdout
描述符
类似于这样:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
void matrix_output_printf(void){
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
printf("%d\t", i+j);
}
printf("\n");
}
}
int main()
{
int fd = open("file.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
int savedStdoutFD = dup(fileno(stdout));
fflush(stdout);
dup2(fd, STDOUT_FILENO);
close(fd);
matrix_output_printf();
fflush(stdout);
dup2(savedStdoutFD, STDOUT_FILENO);
close(savedStdoutFD);
printf("hello\n");
return 0;
}
请注意,此代码在多线程进程中使用时本质上是不安全的。
@chqrlie给出了最佳答案:"一个更好的方法是重写matrix_output_printf
以接受输出流的FILE *
参数,或者文件名的const char *filename
来生成文件"。
英文:
Another option:
- Flush the stream
- Duplicate
stdout
's file descriptor before calling the function, duplicate a file descriptor open to the desired file to the stream's original file descriptor value - Call the function
- Restore the original
stdout
descriptor
Similar to this:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
void matrix_output_printf(void){
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
printf("%d\t", i+j);
}
printf("\n");
}
}
int main()
{
int fd = open("file.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
int savedStdoutFD = dup(fileno(stdout));
fflush(stdout);
dup2(fd, STDOUT_FILENO);
close(fd);
matrix_output_printf();
fflush(stdout);
dup2(savedStdoutFD, STDOUT_FILENO);
close(savedStdoutFD);
printf("hello\n");
return 0;
}
Note that this code is inherently unsafe to use in a multithreaded process.
@chqrlie had the best answer: "A much better approach is to rewrite matrix_output_printf
to take a FILE *
argument for the output stream, or a const char *filename
for the name of the file to produce".
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论