C 在GUI应用程序的代码::块中使用printf

C 在GUI应用程序的代码::块中使用printf,c,user-interface,console,codeblocks,C,User Interface,Console,Codeblocks,出于调试原因,我希望能够在控制台中使用GUI应用程序的printf。我只希望控制台在调试构建目标中可见,而不是在发布构建目标中可见。为此,我右键单击工作区中的项目,选择属性。。。在buildtargets选项卡中,我选择了consoleapplicationintype,并选中了Pause when execution end框。完成此操作后,控制台和GUI窗口会很好地打开,但当我使用printf时,什么都不会发生。如何在带有控制台的GUI应用程序中使用printf 以下是我正在使用的代码的相关

出于调试原因,我希望能够在控制台中使用GUI应用程序的
printf
。我只希望控制台在调试构建目标中可见,而不是在发布构建目标中可见。为此,我右键单击工作区中的项目,选择属性。。。在buildtargets选项卡中,我选择了consoleapplicationintype,并选中了Pause when execution end框。完成此操作后,控制台和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
,出于调试原因,我想检查它的值


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

SDL使用自己的入口点覆盖程序入口点。
关于这方面的更多细节,以及

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

1-重新定义流

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

如果这仍然不起作用,试试看

// 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的情况

从我读到的内容来看,“CON”似乎可以替换为NULL。
(不管它值多少钱。)

freopen方法的另一个变体

freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
有关CONOUT$和CONIN$的更多信息

如果您在使用GNU/Linux BSD、Solaris、Mac Os等之前的版本时遇到问题。。尝试以下方法

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

/* ... */
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
    /* ... */
}
你可以在地图上找到这个例子

2-更改程序的入口点

您还可以取消定义SDL的main,以便第一个调用您的main。
为此,请在主功能之前添加下一个指令

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


/***/


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

关于

3-重建SDL

使用从SDL站点下载的预编译的SDLmain.dll二进制文件,无法阻止stdout/stderr重定向到文本文件。 您可以使用NO_STDIO_REDIRECT compiler标志自己编译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文件

那是从报纸上发来的。欲了解更多信息,请友好访问

源代码中的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
 */
该文件的在线副本

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

#define main    SDL_main
从上面看,这似乎与#unde main methode一致

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

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

你能告诉我们你正在使用的代码吗?@BrandonIbbotson在这里。可能是我尝试使用freopen的副本,它没有在stdout.txt中写入任何内容,但它也没有在控制台中写入任何内容。我尝试了CON和/dev/tty,它们都不起作用。我正在使用Windows。据我所知,您的程序必须是控制台应用程序。你做到了吗?如果这不起作用,我会稍后再与您联系。是的,我在问题中这样说:“我右键单击了工作区中的项目,选择了属性…并在“构建目标”选项卡中选择了类型中的Console应用程序,并选中了“执行结束时暂停”框。”,我选择了SDL项目,这意味着它将自动包含SDL库。这应该与在控制台应用程序中手动包含这些库相同。我的程序本身不应该是一个控制台应用程序,它应该是一个SDL应用程序,控制台只用于调试。我启动了一段SDL代码,没有任何问题要打印到控制台。无论如何,我发现了一些东西,所以我会更新我的答案。它仍然不起作用。我创建了一个名为SDL_InitWitConsole()的宏,我用它来代替SDL_Init(),它看起来是这样的:
#define SDL_InitWithConsole(flags)SDL_Init(flags);文件*ctt=fopen(“CON”,“w”);弗雷奥普(“CON”、“w”、stdout);弗雷Open(“CON”、“r”、stdin);弗雷奥普(“CON”、“w”、stderr);fclose(ctt)
和code
SDL_InitWithFlags(SDL_INIT_视频);printf(“你好”)不打印任何内容。
#include "SDL/SDL.h"


#ifdef WIN32
    #include "sdl_winmain.h"
#else
    #include "SDL/SDL_main.h"
#endif
#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
 */
#define main    SDL_main
/*...*/
perror ("Error"); // the string cannot be formatted 
fprintf (stderr,"Error %s", str_err_msg); // the string can be formatted
/*...*/