2016-08-18 160 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應用程序,控制檯僅用於調試。 –