2016-08-18 104 views
1

的GUI应用程序中使用printf我希望能够在控制台中使用printf与我的GUI应用程序出于调试原因。我只想让控制台在Debug构建目标中可见,而不是Release构建目标。为此,我右键单击Workspace中的项目,选择属性...,然后在构建目标选项卡中,我在类型中选择了控制台应用程序,并在执行结束时选中了“暂停”框。完成后,控制台和GUI窗口打开良好,但是当我使用printf时,没有任何反应。如何在带有控制台的GUI应用程序中使用printf在Code :: Blocks

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

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); 
} 

myVarint,我要检查的调试原因值。

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

+0

你能告诉我们你正在使用的代码吗? – byxor

+0

@BrandonIbbotson在这里。 –

+0

[SDL控制台输出可能在调试时起作用,但不能在使用exe时运行](http://stackoverflow.com/questions/14593783/sdl-console-output-works-when-debuging-but-not-when -run -with-the-exe) –

回答

1

SDL用它自己的入口点覆盖程序入口点。
关于那个更多细节here,thereover there

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

1 - Redireting流

要绕过该行为必须在SDL_Init以下后插入如果添加后没有工作尝试添加它们在主的最顶端。

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

从我看来,它似乎可以用NULL替换“CON”。
对于它的价值。

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的主让你的主要将是第一个被调用。
为此,请在主功能之前添加下一条指令。

/*...*/ 
#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从被重定向到文本文件。 你可以做的是使用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 /包括/ 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 /包括/ SDL/SDL_main.h)不过,我确实发现是

#define main SDL_main 

,似乎是按照从上面的#undef主要方法。

4 - 注意
这可能是有趣的,发送错误信息到stderr,而不是标准输出。为此,请尝试使用perrorfprintf
像这样:

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

我试过使用freopen,它没有在stdout.txt中写入任何内容,但它在控制台中也没有写入任何内容。我尝试了CON和/ dev/tty,都没有工作。我正在使用Windows。 –

+0

从我的理解你的程序必须是一个控制台应用程序。你做到了吗?如果这不起作用,我会在稍后回复你。 –

+0

是的,我在我的问题中这样说:“我右键单击Workspace中的项目,选择Properties ...,然后在Build targets选项卡中,我选择了Console类型的应用程序,并在执行结束时选中了暂停框。但是,在创建项目时,我选择了SDL项目,这意味着它将自动包含SDL库。这应该与在控制台应用程序中手动添加这些库相同。我的程序本身不应该是一个控制台应用程序,它应该是一个SDL应用程序,控制台仅用于调试。 –