【问题标题】:freopen: reverting back to original streamfreopen:恢复到原始流
【发布时间】:2010-12-13 00:36:44
【问题描述】:

我需要将标准输出转发到不同的文件,以分离一些产生的打印并恢复到正常的标准输出。

我用freopen这样切换到文件:

char name[80];
memset(name, 0, 80);
strcpy(name, "./scripts/asm/");
strcat(name, m_func->m_name->m_value);
strcat(name, ".shasm");
freopen(name, "w", stdout);

它确实有效,但在过程结束时(注意标准输出以以前相同的方式多次重定向)我无法将其恢复为原始标准输出。我尝试了以下方法:

freopen("/dev/stdout", "w", stdout);

但它似乎不起作用..只是为了我在macosx上开发的信息。

我该怎么办?

提前致谢

【问题讨论】:

  • 您可能想添加更多细节,当您执行最终的 freopen() 时会发生什么?它返回NULL吗?

标签: c++ c stdio


【解决方案1】:

这可以使用 fileno、dup 和 dup2 调用来实现。我在 linux 上试过这个,不确定这是否可以在 mac 上工作,但我相信你会为你的设置获得一些等效的功能。看看这个示例代码是否适合你。抱歉,代码中缺少错误处理。 :)

    #include <stdio.h>

    main()
    {
        int    fd;
        fpos_t pos;

        printf("stdout, ");

        fflush(stdout);
        fgetpos(stdout, &pos);
        fd = dup(fileno(stdout));
        freopen("stdout.out", "w", stdout);

        f();

        fflush(stdout);
        dup2(fd, fileno(stdout));
        close(fd);
        clearerr(stdout);
        fsetpos(stdout, &pos);        /* for C9X */

        printf("stdout again\n");
    }

    f()
    {
    printf("stdout in f()");
    }

【讨论】:

  • 将其修改为 #include 然后检查 fgetpos/fsetpos 调用的返回值会显示 Linux 上的问题: if (fgetpos(stdout, &pos)) perror("fgetpos") ;
【解决方案2】:

这似乎是解决您问题的一种迂回方式。为什么不直接使用fopen() 打开每个文件,然后使用fputsfprintffwrite 等写入其FILE *?无需重定向标准输出。

【讨论】:

  • 可能是因为(很多)代码在没有指定输出流的情况下编写,例如只使用普通的 printf() 调用。重定向标准输出是一种“包装”该代码并将其写入所需位置而不更改它的方式。当然只是猜测。
  • @unwind 你的猜测是正确的,这是 freopen 最有可能的用例。
  • 我实际上可以确认这就是原因。它是一个编译器,我在创建它时总是使用 printf 来打印 asm 代码(例如 MOV $1、4.5f),现在我不想浪费时间替换东西..
  • 一个简单的 sedperl 脚​​本来完成所有替换并修复损坏的代码会比这些丑陋的黑客要好得多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-31
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 2015-12-11
  • 2017-07-10
  • 1970-01-01
相关资源
最近更新 更多