我有一个Windows Win32 / GUI应用程序,有时会向stdout
和stderr
输出有趣的输出,所以我想做的是将输出捕获到申请退出后要审核的文件。
问题是,我可以成功调用freopen_s()
将stdout
输出捕获到文件中,或我可以使用它将stderr
输出捕获到文件,但尝试同时执行两个操作只会产生带有munged数据的截断文件。
下面是一个简单的程序,可以重现问题;如果我注释掉两个freopen_s()
调用中的任何一个,那么我会在创建的blah.txt
文件中获得预期的输出(即两个文本行中的一个),但是我所做的是什么就像最终得到包含两个文本行的blah.txt
一样。
这可能在Windows下吗?我可以回过头来创建两个不同的文件(例如blah_stdout.txt
和blah_stderr.txt
),但我不愿意,因为那时我必须手动重建stdout和stdout的相对顺序。生成了stderr输出。
int main(int argc, char *argv[])
{
const char * outFileName = "blah.txt";
FILE * junk1 = NULL, junk2 = NULL;
if (freopen_s(&junk1, outFileName, "w", stdout) != 0) abort();
if (freopen_s(&junk2, outFileName , "w", stderr) != 0) abort();
printf("This text was printed to stdout and should appear in blah.txt\n");
fprintf(stderr, "This text was printed to stderr and should appear in blah.txt\n");
return 0;
}
答案 0 :(得分:1)
“w”打开模式记录为
打开一个空文件进行写入。如果给定文件存在,则其内容将被销毁。
但即使是“w +”和“a”也会失败。
如果您使用的是具有dup2的CRT,您可以这样做:
#include <io.h> // MS CRT
...
FILE * junk1 = NULL;
if (freopen_s(&junk1, outFileName, "w", stdout) != 0) abort();
_dup2(1, 2); // Assign stderr to same file as stdout
当我测试它时,这段代码将两行写入文件,但从评论中可以明显看出这可能并非总是如此。较旧版本的Visual Studio更有可能发挥作用。
如果您愿意抛弃所有可移植性,您也可以直接访问FILE对象(struct _iobuf
)后面的结构(_iob
/ __iob_func
)并覆盖成员使用其他文件的值。这是not possible in VS 2015 and later:
FILE封装:在以前的版本中,FILE类型在&lt; stdio.h&gt;中完全定义,因此用户代码可以通过其内部进入FILE和muck。我们重构了stdio库以改进库实现细节的封装。作为其中的一部分,定义的FILE现在是一个不透明的类型,其成员无法从CRT本身外部访问。