是否可以从标准输出读取?
Is it possible to read from stdout?
如果我使用 printf ("Hello!");
,有什么方法可以读取我打印到标准输出中的内容吗?
我看到了 C language. Read from stdout(它使用管道)但它不起作用:
#define _XOPEN_SOURCE
#include <stdio.h>
#include <unistd.h>
#define DIM 10
int main(void)
{
char s[DIM];
int fds[2];
pipe(fds);
dup2(fds[1], fileno(stdout)); //I added fileno()
printf("Hello world!");
read(fds[0], s, DIM);
printf("\n%s",s);
return 0;
}
我也试过使用文件描述符,但都不起作用:
#define _XOPEN_SOURCE
#include <stdio.h>
#include <unistd.h>
#define DIM 10
#define MYFILE "/path/file"
int main(void)
{
FILE *fd;
char s[DIM];
fd = fopen(MYFILE,"w+");
dup2(STDOUT_FILENO, fileno(fd));
printf("Hello world!");
fseek(fd, 0, SEEK_SET);
fgets(s, DIM, fd);
printf("\n%s",s);
return 0;
}
我该怎么办?
通常不会,除非标准输出已重定向到文件。写入标准输出的函数(如 printf()
)不会在您的进程中的任何地方记录它们的输出,并且除了普通文件*之外,无法从任何其他文件中读取您之前的输出。例如,如果您的进程正在将其输出打印到终端,尝试从终端读取数据将返回用户输入的内容,而不是您之前输出的内容。
您的第二个程序几乎 可以运行。不过,您需要先解决一些小问题:
第一个 printf()
的输出将不会输出,因为它缺少换行符。要么添加换行符,要么调用 fflush(stdout)
强制输出它。
您正在尝试 printf()
您的结果,但标准输出仍指向该文件,因此您永远看不到它。覆盖标准输出后显示内容的最简单方法是使用 fprintf(stderr, ...)
.
(*: 或者某些行为很像文件的东西,比如块设备或命名管道。但你可能不会使用它们。)
如果stdout是一个文件,你可以在上面打开另一个文件描述符并查找和读取。另一方面,如果它是管道,则不能。写入管道的数据只能读取一次。如果该管道的读取端与 tty 相关联,那么它将被设备驱动程序读取并且不再可供您的进程读取。 dup
ing 文件描述符不会使数据可用两次,因此使用 dup2 的方法无法工作(实际上,dup2(fds[1], STDOUT_FILENO)
首先关闭 STDOUT_FILENO,所以现在您只需写入管)。你可以 fork 一个复制数据的进程,或者使用 splice/tee 系统调用来复制数据,但你真的需要问:你为什么要这样做?
访问这里:
https://github.com/pouyanh/isolated-iostream
这是关于调用另一个函数时stdout的透明输出缓冲
如果您使用 Linux,您可以使用 fmemopen:
#include <iostream>
#include <stdio.h>
char mybuffer[BUFF_SIZE];
FILE * pFile = fmemopen(mybuffer, BUFF_SIZE, "w");
std::swap(stdout, pFile); //swap pFile to stdout
rc = someFunctionWritingToStdout();
std::swap(stdout, pFile); //restore
fclose(pFile); // flush and close stream
cout << "-....-" << endl;
cout << mybuffer << endl;
cout << "-....-" << endl;
如果我使用 printf ("Hello!");
,有什么方法可以读取我打印到标准输出中的内容吗?
我看到了 C language. Read from stdout(它使用管道)但它不起作用:
#define _XOPEN_SOURCE
#include <stdio.h>
#include <unistd.h>
#define DIM 10
int main(void)
{
char s[DIM];
int fds[2];
pipe(fds);
dup2(fds[1], fileno(stdout)); //I added fileno()
printf("Hello world!");
read(fds[0], s, DIM);
printf("\n%s",s);
return 0;
}
我也试过使用文件描述符,但都不起作用:
#define _XOPEN_SOURCE
#include <stdio.h>
#include <unistd.h>
#define DIM 10
#define MYFILE "/path/file"
int main(void)
{
FILE *fd;
char s[DIM];
fd = fopen(MYFILE,"w+");
dup2(STDOUT_FILENO, fileno(fd));
printf("Hello world!");
fseek(fd, 0, SEEK_SET);
fgets(s, DIM, fd);
printf("\n%s",s);
return 0;
}
我该怎么办?
通常不会,除非标准输出已重定向到文件。写入标准输出的函数(如 printf()
)不会在您的进程中的任何地方记录它们的输出,并且除了普通文件*之外,无法从任何其他文件中读取您之前的输出。例如,如果您的进程正在将其输出打印到终端,尝试从终端读取数据将返回用户输入的内容,而不是您之前输出的内容。
您的第二个程序几乎 可以运行。不过,您需要先解决一些小问题:
第一个
printf()
的输出将不会输出,因为它缺少换行符。要么添加换行符,要么调用fflush(stdout)
强制输出它。您正在尝试
printf()
您的结果,但标准输出仍指向该文件,因此您永远看不到它。覆盖标准输出后显示内容的最简单方法是使用fprintf(stderr, ...)
.
(*: 或者某些行为很像文件的东西,比如块设备或命名管道。但你可能不会使用它们。)
如果stdout是一个文件,你可以在上面打开另一个文件描述符并查找和读取。另一方面,如果它是管道,则不能。写入管道的数据只能读取一次。如果该管道的读取端与 tty 相关联,那么它将被设备驱动程序读取并且不再可供您的进程读取。 dup
ing 文件描述符不会使数据可用两次,因此使用 dup2 的方法无法工作(实际上,dup2(fds[1], STDOUT_FILENO)
首先关闭 STDOUT_FILENO,所以现在您只需写入管)。你可以 fork 一个复制数据的进程,或者使用 splice/tee 系统调用来复制数据,但你真的需要问:你为什么要这样做?
访问这里:
https://github.com/pouyanh/isolated-iostream
这是关于调用另一个函数时stdout的透明输出缓冲
如果您使用 Linux,您可以使用 fmemopen:
#include <iostream>
#include <stdio.h>
char mybuffer[BUFF_SIZE];
FILE * pFile = fmemopen(mybuffer, BUFF_SIZE, "w");
std::swap(stdout, pFile); //swap pFile to stdout
rc = someFunctionWritingToStdout();
std::swap(stdout, pFile); //restore
fclose(pFile); // flush and close stream
cout << "-....-" << endl;
cout << mybuffer << endl;
cout << "-....-" << endl;