gpt4 book ai didi

c++ - 自定义应用程序控制台和标准错误

转载 作者:太空狗 更新时间:2023-10-29 23:06:39 26 4
gpt4 key购买 nike

我正在编写一个类来从应用程序内部显示自定义控制台。我也在使用 glog将消息记录到一个文件,同时记录到 stderr。我怎样才能让我的控制台类听 stderr?

我想制作一个自定义的 fstream 并做类似的事情:

CustomStream cs;
auto original_buf = std::cerr.rdbuf(cs.rdbuf());

并调用 stream operator <<发送到控制台类。

或者直接从std::filebuf继承并调用:

CustomFilebuf fb;
auto original_buf = std::cerr.rdbuf(&fb);

这是正确的做法吗?我搜索了一些示例代码,但找不到太多。

Edit1:我尝试使用流 tee,但 glog 日志记录为 stderr而不是 std::cerr ,所以我无法获取任何数据。

最佳答案

我不确定这是否与您的问题相关,但是...

ISO C99 在 7.19.5.3 第 6 段中说:

When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function [...], and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file.

也有人说从 stderr 读取是“未定义的行为”...

虽然你可以从 stderr 读取,但只要你在读取之前刷新:

fwrite("x", 1, 1, stderr);
fflush(stderr);
fgetc(stderr);

另请查看 How do I read stdout/stderr output of a child process correctly?


对于任何想在 Win32 应用程序中将标准输出重定向到控制台窗口的人来说,<强> AllocConsole .

我什至创建了一个简单(琐碎)的函数来将标准输出重定向到控制台窗口:

#include <fstream>
#include <io.h>
#include <fcntl.h>

#define cMaxConsoleLines 500

void ReadyConsole() {

short int hConHandle;
long lStdHandle;

CONSOLE_SCREEN_BUFFER_INFO coninfo;

FILE *fp;

// Allocate a console for the program
AllocConsole();

// set the screen buffer to be big enough to let us scroll text
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);

coninfo.dwSize.Y = cMaxConsoleLines; // The max number of lines for the console!

SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);


// Redirect STDOUT to the console
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);

fp = _fdopen(hConHandle, "w"); // Writing to the console

*stdout = *fp;

setvbuf(stdout, NULL, _IONBF, 0);
// -------------------------------


// Redirect STDIN to the console
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);

fp = _fdopen(hConHandle, "r"); // Reading from the console

*stdin = *fp;

setvbuf(stdin, NULL, _IONBF, 0);
// ------------------------------


// Redirect STDERR to the console
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);

fp = _fdopen(hConHandle, "w"); // STDERR writing to the console!

*stderr = *fp;

setvbuf(stderr, NULL, _IONBF, 0);
// ------------------------------


// Point the console to STDIO
std::ios::sync_with_stdio();

}

如果您希望控制台仅用于调试,请确保包含 <crtdbg.h> ,它定义应用程序是否处于 Debug模式(对于 VC++),然后,例如您可以添加:

#ifdef _DEBUG
// The file with the ReadyConsole function
#include <DebugStuff.h>
#endif

并使用它

#ifdef _DEBUG
ReadyConsole(); // Ready the console for debugging
#endif

#ifdef _DEBUG
fprintf(stdout, "Position, Line 1, DEBUG-INFO-HERE");
cout << "COUT is working!"; // NOTE, for cout, you will need <iostream>
#endif

这是一个额外的小功能(它将消息记录到 stderr stderr.log 文件中)

void StdErr(char* Error) {

fprintf(stderr, Error);
FILE* FP = fopen("stderr.log", "a");
fputs(Error, FP);
fclose(FP);

}

关于c++ - 自定义应用程序控制台和标准错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15046503/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com