gpt4 book ai didi

c - 在 Code::Blocks 的 GUI 应用程序中使用 printf

转载 作者:太空宇宙 更新时间:2023-11-04 03:28:45 25 4
gpt4 key购买 nike

出于调试原因,我希望能够在我的 GUI 应用程序的控制台中使用 printf。我只希望控制台在调试构建目标中可见,而不是在发布构建目标中可见。为此,我右键单击工作区中的项目,选择属性...,然后在构建目标选项卡中,我选择控制台应用程序类型并选中执行结束时暂停框。完成此操作后,控制台和 GUI 窗口可以正常打开,但是当我使用 printf 时什么也没有发生。如何在带有控制台的 GUI 应用程序中使用 printf

这是我正在使用的代码的相关部分:

SDL_Init(SDL_INIT_VIDEO);
putenv("SDL_VIDEO_CENTERED=center");
SDL_WM_SetCaption("Railroad Builder",NULL);
SDL_WM_SetIcon(IMG_Load(strcat_const(parentFolder(exePath),"/icon.png")),NULL);
SDL_SetVideoMode(MAIN_WINDOW_WIDTH,MAIN_WINDOW_HEIGHT,32,SDL_OPENGL);
int running = 1;
while(running){
printf("myVar = %d",myVar);
}

myVar 是一个 int,出于调试原因,我想检查它的值。

这个问题和this不一样因为在另一个问题中,他们已经知道从IDE运行程序时如何在控制台中编写,而这道题是关于如何在控制台中编写的。

最佳答案

SDL 用它自己的入口点覆盖程序入口点。
更多详情 here , thereover there .

默认情况下,标准输出 ( stdout, stdin and stderr ) 被重定向到文件,这些文件与它们保存的流的内容具有相同的名称。
它们应该在您的程序目录中。

1 - 重定向流

要绕过该行为,您必须在 SDL_Init 之后插入以下内容。 如果 add after 不起作用,请尝试将它们添加到 main 的最顶部。

freopen ("CON", "w", stdout);
freopen ("CON", "r", stdin);
freopen ("CON", "w", stderr);

如果还是不行试试。

// Start : edit
SDL_Init (...)
FILE * ctt = fopen("CON", "w" ); // c
// or
ofstream ctt("CON"); // c++
// End : edit


freopen ("CON", "w", stdout);
freopen ("CON", "r", stdin);
freopen ("CON", "w", stderr);
/* ... */


// Start : edit
fclose (ctt); // c
// or
ctt.close(); // c++
// End : edit

了解 CON here .

从我读到的内容来看,“CON”似乎可以用 NULL 代替。
(物有所值。)

freopen(NULL,"w",stdout);
freopen(NULL,"w",stdout);
freopen(NULL,"w",stderr);

freopen 方法的另一种变体。

freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);

关于 CONOUT$ 和 CONIN$ 的更多信息 here .

如果您在使用 GNU/Linux BSD、Solaris、Mac Os 等时遇到问题,请尝试以下操作。

freopen ("/dev/tty", "w", stdout);
freopen ("/dev/tty", "r", stdin);
freopen ("/dev/tty", "w", stderr);

应用该方法应该如下面的代码所示。

/* ... */
int main {
SDL_Init(SDL_INIT_VIDEO);


/* start : redirecting the streams to the console */
FILE * ctt = fopen("CON", "w" ); // Edit


freopen ("CON", "w", stdout);
freopen ("CON", "r", stdin);
freopen ("CON", "w", stderr);
/* end : redirecting the streams to the console */


/*start : your code */
putenv("SDL_VIDEO_CENTERED=center");
SDL_WM_SetCaption("Railroad Builder",NULL);
SDL_WM_SetIcon(IMG_Load(strcat_const(parentFolder(exePath),
"/icon.png")),NULL);
SDL_SetVideoMode(MAIN_WINDOW_WIDTH,MAIN_WINDOW_HEIGHT,32,
SDL_OPENGL);
int running = 1;
while(running){
printf("myVar = %d",myVar);
}
/* end : your code */


/* ... */
fclose (ctt); // Edit
/* ... */
}

您可以在 SDL faq 上找到该示例.

2 - 更改程序的入口点

您也可以取消定义 SDL 的 main,这样您的 main 将第一个被调用。
为此,请在 main 函数之前添加下一条指令。

/*...*/
#ifdef main
#undef main // Prevent SDL from overriding the program's entry point.
#endif


/***/


int main(int argc, char **argv){
/*...*/
}

/*...*/


#ifdef __MINGW32__ // It can be __MINGW64__. Chose according to your architecture.
#undef main // Prevent SDL from overriding the program's entry point.
#endif


//or


#if defined(__MINGW32__) || defined(__MINGW64__)
#undef main // Prevent SDL from overriding the program's entry point.
#endif


/*...*/


int main(int argc, char **argv){
/*...*/
}

关于MINGW32 and MINGW64

3 - 重建 SDL

使用从 SDL 站点下载的预编译 SDLmain.dll 二进制文件,您无法阻止 stdout/stderr 被重定向到文本文件。您可以做的是使用 NO_STDIO_REDIRECT 编译器标志自行编译 SDLmain,或者根本不使用 SDLmain。

请注意,不使用 SDLmain 会破坏可移植性,因此不推荐使用。

也就是说,有时将 stdout.txt 和 stderr.txt 写入可执行文件所在的目录会更好。

你可以用一些小技巧来做到这一点:

#include "SDL/SDL.h"


#ifdef WIN32
#include "sdl_winmain.h"
#else
#include "SDL/SDL_main.h"
#endif

其中sdl_winmain.h在你自己的工程目录下,是SDL源码包中src/main/SDL_win32_main.c的重写副本。这样您仍然可以在其他平台上使用,但不会在 Windows 中随处获取 stdout/stderr 文件。

来自 SDL faq .如需更多信息,请获取 wiki友好。

3.5 源码
在源代码 (~/SDL2-2.0.4/include/SDL_main.h) 中,我发现了以下内容

#ifndef SDL_MAIN_HANDLED
#if defined(__WIN32__)
/* On Windows SDL provides WinMain(), which parses the command line and passes
the arguments to your main function.


If you provide your own WinMain(), you may define SDL_MAIN_HANDLED
*/

source code 的在线副本.

如果定义 NO_STDIO_REDIRECT 没有成功,请尝试 SDL_MAIN_HANDLED。
在 SDL-1.2.15 (~/SDL-1.2.15/include/SDL/SDL_main.h) 中找不到它,但是,我找到的是

#define main    SDL_main

这似乎与上面的#undef main 方法一致。

4 - 注意
将错误消息发送到 stderr 而不是 stdout 可能会很有趣。为此,请尝试使用 perrorfprintf .
像这样:

/*...*/
perror ("Error"); // the string cannot be formatted
fprintf (stderr,"Error %s", str_err_msg); // the string can be formatted
/*...*/

关于c - 在 Code::Blocks 的 GUI 应用程序中使用 printf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39015282/

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