【问题标题】:xprintf doesn't use stdout. How does it still print on screen?xprintf 不使用标准输出。它如何仍然在屏幕上打印?
【发布时间】:2012-11-15 08:26:29
【问题描述】:

对于工作中的C++ 项目,我使用GLPK(用C 编写的Gnu 线性规划工具包)。当我在控制台应用程序中使用某些程序时,会从GLPK 生成自动输出。

现在,在我将所有内容打包到 GUI 中之后,我想使用以前显示的文本。所以我将标准输出和标准错误重定向到文件。 (我检查了它在我的应用程序中与printf("Hallo World"); 一起工作正常)。

问题是GLPK 格式的文本没有出现在文件中。经过一番研究,我发现使用了声明xprintf(...)。 (老实说,我不知道xprintf 的作用以及与printf 的区别是什么。)

谁能解释一下:

  1. 在没有标准输出的情况下如何在屏幕上打印文本。
  2. 如何获得自动生成的输出到文件或流或任何我可以处理的东西。

【问题讨论】:

  • 你检查过它是否使用stderr吗?
  • 也许就是这么简单。我以为我已将 stderr 重定向到 error.txt。但是我打印错误的测试没有出现在error.txt中。我必须仔细检查。
  • stderr 被重定向到 error.txt。 (检查fprintf( stderr, "ERROR1"); 奇怪perror("ERROR2"); 没有出现在error.txt 中(我不得不说那是我第一次使用该语句并且我不熟悉它的行为)
  • @MartinHoratschek 标准的perror 函数总是打印到stderr,所以如果你在进程完成后没有在错误文件中看到它的输出,要么你(或GLPK)没有使用标准perror 函数,或者您没有正确重定向stderr(您的评论说您已经测试过)。
  • 您使用的是哪个版本的 GLPK?如何将stdout 重定向到文件?

标签: c++ c printf stdout


【解决方案1】:

GLPK 内部使用的xprintfglp_printf 的别名)在正常情况下写入stdout(对于最新的 GLPK 版本 4.47)。

有几种方法可以改变glp_printf 的行为:

  • 使用glp_term_out(GLP_OFF)禁用输出
  • 使用glp_term_hook 函数安装一个钩子,该函数可以将输出重定向到任何钩子想要的地方
  • 将输出的副本写入文本文件 - 可以使用 glp_open_tee 函数进行设置

如果您没有使用上述任何方法,并且仍然无法重定向 stdout 输出,那么您重定向输出的方式可能有问题。

【讨论】:

  • 我接受这个作为我的答案,因为它为我的主要问题提供了解决方案。我刚刚使用了glp_open_tee("tee.tee");,得到了我想要的一切。 stdout 的重定向只是我尝试执行该语句的功能。我感谢所有提供帮助的人。
【解决方案2】:
  1. 如何在没有标准输出的情况下在屏幕上打印文本。

您的平均stdout 是默认情况下碰巧连接到终端的输出流。你可以用它做任何可以用流做的事情,包括reopen()它到一个文件中。

正如您可以使用fopen() 创建另一个写入文件的流一样,您也可以使用它创建另一个写入终端的流(在Linux 中为/dev/tty)。写入该流的输出将出现在您的终端上,尽管没有通过标准输出。

stdout 只是一个方便的默认设置,绝不是访问终端的唯一方法。

【讨论】:

    【解决方案3】:

    stdout 默认是缓冲的,所以文本只会在每一个新行之后刷新。 您的某个库甚至 xprintf 本身可能会改变标准输出的行为。 基本上,如果该输出不以换行符结尾,则不能保证看到以前的 printf() 输出。

    尝试使用:

    fflush (stdout);
    

    在 xprintf 之后。

    fflush 在 stdio.h 中

    通常 xprintf 是非分配的 printf。

    【讨论】:

    • 我想知道在这种情况下“通常”是什么意思。 xprintf() 不是标准函数,我找不到任何关于它的文档ad hoc
    • 我经常编辑。非分配 printf 的一种实现是:xprintf.
    • 我自己写了非malloc'ing printf(),谢谢。 ;-) 我觉得从标准函数中不必要地调用malloc() 有点脑残——在 printf() 的上下文中它不必要的。 ;-)
    • 只是好奇 - 为什么printf() 需要动态内存? glibc(或其他常见的 C 运行时库)会做这样的事情吗?
    • 在 stdio-common/vfprintf.c 中有很多调用 malloc 和 printf() 似乎解决使用 vfprintf。动态内存可能是在那里实现的,以创建用于更改字符表示等的消耗性缓冲区。
    【解决方案4】:

    在 GLPK 中,xprintf_glp_lib_xprintf 的宏别名(在 glplib.h 中定义)。

    xprintf()glplib04.c 中实现。默认情况下,它会输出到stdout(通过同一源文件中的xputc() 函数)。有多种配置选项可以改变xputc() 的行为。

    您可能想在_glp_lib_xprintf() 上设置一个断点并逐步查看发生了什么。

    【讨论】:

    • 我很想尝试一下。但是我链接了glpk_4_47.dll,我没有看到在那里设置断点的方法。
    • 我认为您应该只需要构建带有符号的 DLL 的调试版本。
    猜你喜欢
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-02
    • 2013-09-01
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    相关资源
    最近更新 更多