【问题标题】:redirect stdout/stderr to function in C将 stdout/stderr 重定向到 C 中的函数
【发布时间】:2016-06-11 06:20:16
【问题描述】:

我想将 stdout 和 stderr 重定向到一个函数并编写一个简单的代码。 fprintf 没问题,但是当我在没有 \r 的情况下使用 printf 时,流会传递到终端!

#include <stdio.h>
static ssize_t file_write(void *c, const char *buf, size_t size)
{
  FILE * pFile;
  pFile = fopen ("output.txt","w");
  fprintf(pFile, "%s", buf);
  fclose (pFile);

return size;
}

void redirect()
{
  FILE *stream;
  stream=fopencookie(NULL, "w", (cookie_io_functions_t) {(ssize_t) 0,  file_write, 0, 0});
  setbuf(stdout, NULL);
  stdout = stream;
  setbuf(stderr, NULL);
  stderr = stream;
}

int main()
{
  redirect();
  fprintf(stderr,"1-stderr test\n");
  fprintf(stdout, "2-stdout test\n");
  printf("3-printf with r test\n\r");
  printf("4-printf without r test\n");

return 0;
}

文件“输出.txt”:

1-stderr 测试
2-stdout 测试
带 r 测试的 3-printf

终端输出:

$ ./sample
4-printf 没有 r 测试

【问题讨论】:

  • 1.整理缩进 2. 为什么不检查fopen 的返回值 3. fprintf(pFile,buf); - 希望buf 中不包含%
  • 您使用buf 作为格式字符串。如果它包含任何 % 字符,这将非常可怕地失败。要么使用fprintf(pFile, "%s", buf),要么调用fwrite而不是fprintf
  • 你也可以打电话给fputs而不是fprintf。这可能是最简单的。
  • 不要尝试这样做!即使它在一个系统上工作,它也不能在另一个系统上工作或与另一个版本的标准库一起工作。我的建议是在这种情况下始终使用 fprintf-fputs,并在您不想重定向时让流成为标准输出。

标签: c function redirect stdout


【解决方案1】:

您不能从程序中的函数“重定向”标准输入或标准输出。

但是,您可以创建一对管道并用这些管道替换标准输入和输出,并让另一个函数(可能在另一个线程甚至子进程中)使用管道的另一端与该函数进行通信。

你当然可以使用例如setvbufstdinstdout 的缓冲区更改为您提供的一对缓冲区,然后您可以像任何其他内存缓冲区(即数组)一样直接从缓冲区读取或写入缓冲区。不过我不推荐它,它很脆弱并且容易出错。

但是在这种情况下,您似乎想要的是所有写入stdout 的内容都应该转到该文件。在那种情况下(比如使用管道),没有标准的 C 方法来处理它,但是您需要使用操作系统特定的功能。然后,如果您在 POSIX 平台(如 Linux 或 OSX)上,您可以告诉操作系统为您的文件复制底层文件描述符,并说 STDOUT_FILNO(这是用于 stdout 的文件描述符)是您打开的文件的文件描述符的副本。然后对stdout 的所有写入都将写入您的文件。为此,您需要使用the dup2 system call

【讨论】:

    猜你喜欢
    • 2014-07-22
    • 1970-01-01
    • 2022-01-18
    • 2016-02-19
    • 2011-05-14
    • 2012-08-07
    • 2011-12-27
    • 1970-01-01
    • 2011-07-22
    相关资源
    最近更新 更多