在debuging时,SDL控制台输出有效,但在使用exe运行时则不然

时间:2020-12-08 20:43:29

I am writing an experimental networking program, basically a test program for learning networking. I am using SDL and SDL_net in Code::Blocks with mingw, so the console output was being directed to stdout.txt. I searched around and found that you can fix this by including after SDL_Init():

我正在写一个实验性的网络程序,基本上是一个学习网络的测试程序。我在使用mingw的Code :: Blocks中使用SDL和SDL_net,因此控制台输出被定向到stdout.txt。我四处搜索,发现你可以通过在SDL_Init()之后加入来解决这个问题:

freopen("CON", "w", stdout); //stops redirect of output
freopen("CON", "w", stderr); //and errors...

This worked perfectly, but only when building and running the program in the IDE: when run outside of the IDE ( e.g. double clicking on the program) the program runs properly, with the exception of the console output, which is still blank. As the program is supposed to be a console program this is a severe problem... I don't want to have to always run the program in the IDE to use it.

这非常有效,但只有在IDE中构建和运行程序时:在IDE外部运行时(例如双击程序)程序才能正常运行,但控制台输出除外,它仍然是空白的。由于该程序应该是一个控制台程序,这是一个严重的问题...我不想总是在IDE中运行该程序来使用它。

Any solution is apreciated but I would prefer that it was an alteration to the code, although in a pinch a batch file will do (I've read a couple of posts where this is the only thing that works, but they didn't go into much detail, so I can't replicate it). Thanks.

任何解决方案都是一个解决方案,但我更希望它是对代码的改动,尽管在批处理文件中会有一些改进(我已经阅读了几个帖子,这是唯一可行的,但是他们没有去进入很多细节,所以我不能复制它)。谢谢。

4 个解决方案

#1


0  

Did you take a look at the SDL Console FAQ?

您是否看过SDL控制台常见问题解答?

They provide many suggestions, including:

他们提供了许多建议,包括:

First try

第一次尝试

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

If it doesn't work (like in your case), try

如果它不起作用(如你的情况),请尝试

#include <fstream>
#include <iostream>
using namespace std;
....
ofstream ctt("CON");
freopen( "CON", "w", stdout );
freopen( "CON", "w", stderr );
...
ctt.close();

OR

要么

FILE * ctt = fopen("CON", "w" );
freopen( "CON", "w", stdout );
freopen( "CON", "w", stderr );
...
ctt.close();

Another option is to recompile the SDLmain library or add the SDLmain code to your project and stop linking against the library.

另一个选项是重新编译SDLmain库或将SDLmain代码添加到项目中并停止链接到库。

#2


2  

For (MinGW) SDL 2.0 users

SDL 2.0 disables the console by default, or rather, it does not enable it. Since compiling with -mwindows disables the console, stdout does not point to anything. SDL_Log is a little fancier and can find the console using the windows API, but it can't capture stdin, because cmd.exe stole it :(.

SDL 2.0默认情况下禁用控制台,或者更确切地说,它不启用它。由于使用-mwindows进行编译会禁用控制台,因此stdout不会指向任何内容。 SDL_Log是一个有点发烧友,可以使用Windows API找到控制台,但它无法捕获标准输入,因为cmd.exe偷了它:(。

SDL does not claim the console for various reasons, most likely because the program was compiled with -mwindows. Specifying WinMain as the entry point might also make cmd.exe reclaim the console. From what I've read SDL_main might redirect stdout and stderr.

SDL因各种原因没有声明控制台,很可能是因为该程序是使用-mwindows编译的。将WinMain指定为入口点也可能使cmd.exe回收控制台。从我读过的内容来看,SDL_main可能会重定向stdout和stderr。

You could probably get away with #undef'ing main, and/or

你可能可以使用#undef'ing main和/或

  • call AllocConsole(); after SDL_init(...);
  • 调用AllocConsole();在SDL_init(...)之后;
  • use freopen("CON", stdout)
  • 使用freopen(“CON”,stdout)
  • compile without -mwindows (#undef'ing main doesn't seem to have any effect)
  • 没有-mwindows编译(#undef'ing main似乎没有任何影响)

but you should really just redirect stdout to e.g. cat, with main | cat (Always follow the rule "Don't #undef main unless you have to").

但你应该只是将stdout重定向到例如猫,主要| cat(始终遵循规则“除非必须,否则不要#undef main”)。

TL; DR

To capture stdout for MinGW, simply redirect your program to cat: main | cat. This is a hack which simply makes sure stdout and stderr don't point to nothing.
To capture both stdin and stdout, compile without -mwindows to create a Windows console application. This will open a new window if necessary.

要捕获MinGW的标准输出,只需将程序重定向到cat:main |猫。这是一个黑客,只是确保stdout和stderr不指向任何东西。要捕获stdin和stdout,请在不使用-mwindows的情况下进行编译以创建Windows控制台应用程序。如有必要,这将打开一个新窗口。

Note: It is especially important to flush output when using one of the above methods. Relying on line buffering is bad practice anyway.

注意:使用上述方法之一冲洗输出尤为重要。无论如何,依靠线缓冲是不好的做法。

#3


1  

(I couldn't post this yesterday because I didn't have enough reputation)

(我昨天不能发帖,因为我没有足够的声誉)

Ok, did a little experimenting on the lines of the batch file. My resulting and (almost) working batch file:

好的,对批处理文件的行进行了一些实验。我的结果和(几乎)工作批处理文件:

program.exe

Didn't realise it would be this simple, but still can't understand why double clicking on the program doesn't work. I said almost working because after the client connects to the server the console blanks out, so there is still an issue. So, I still would really apreciate any help with this problem.

没有意识到这将是这么简单,但仍然无法理解为什么双击该程序不起作用。我说几乎工作,因为在客户端连接到服务器后控制台空白,所以仍然存在问题。所以,我仍然会对这个问题提供任何帮助。

(End of yesterday's prospective post)

(昨天的预期结束)

(Begining of today's answer)

(开始今天的答案)

I tried Emartel's suggestions but it still didn't work. Did some testing and discovered that an infinite loop of printing a empty string was causing the issue of the blank screen after connecting the client. Fixed the loop and now it works properly, although I still have to use the batch script.

我尝试了Emartel的建议,但它仍然没有用。做了一些测试并发现打印空字符串的无限循环导致连接客户端后出现空白屏幕问题。修复了循环,现在它正常工作,虽然我仍然需要使用批处理脚本。

Would apreciate knowing if someone ever figures out why double-clicking doesn't work.

如果有人弄清楚为什么双击不起作用,我们会知道吗?

#4


0  

Two reasons:

两个原因:

  • With SDL the console is disabled. SDL uses windows, not consoles.

    使用SDL,控制台被禁用。 SDL使用的是Windows,而不是控制台。

  • SDL redirects the standard output (both cout and printf()) to a file named stdout.txt in the same folder where the *.exe is located directory.

    SDL将标准输出(cout和printf())重定向到* .exe所在目录所在的同一文件夹中名为stdout.txt的文件。

You can use:

您可以使用:

std::cout << "Hello World";

And the message will be stored in the file stdout.txt.

消息将存储在stdout.txt文件中。

#1


0  

Did you take a look at the SDL Console FAQ?

您是否看过SDL控制台常见问题解答?

They provide many suggestions, including:

他们提供了许多建议,包括:

First try

第一次尝试

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

If it doesn't work (like in your case), try

如果它不起作用(如你的情况),请尝试

#include <fstream>
#include <iostream>
using namespace std;
....
ofstream ctt("CON");
freopen( "CON", "w", stdout );
freopen( "CON", "w", stderr );
...
ctt.close();

OR

要么

FILE * ctt = fopen("CON", "w" );
freopen( "CON", "w", stdout );
freopen( "CON", "w", stderr );
...
ctt.close();

Another option is to recompile the SDLmain library or add the SDLmain code to your project and stop linking against the library.

另一个选项是重新编译SDLmain库或将SDLmain代码添加到项目中并停止链接到库。

#2


2  

For (MinGW) SDL 2.0 users

SDL 2.0 disables the console by default, or rather, it does not enable it. Since compiling with -mwindows disables the console, stdout does not point to anything. SDL_Log is a little fancier and can find the console using the windows API, but it can't capture stdin, because cmd.exe stole it :(.

SDL 2.0默认情况下禁用控制台,或者更确切地说,它不启用它。由于使用-mwindows进行编译会禁用控制台,因此stdout不会指向任何内容。 SDL_Log是一个有点发烧友,可以使用Windows API找到控制台,但它无法捕获标准输入,因为cmd.exe偷了它:(。

SDL does not claim the console for various reasons, most likely because the program was compiled with -mwindows. Specifying WinMain as the entry point might also make cmd.exe reclaim the console. From what I've read SDL_main might redirect stdout and stderr.

SDL因各种原因没有声明控制台,很可能是因为该程序是使用-mwindows编译的。将WinMain指定为入口点也可能使cmd.exe回收控制台。从我读过的内容来看,SDL_main可能会重定向stdout和stderr。

You could probably get away with #undef'ing main, and/or

你可能可以使用#undef'ing main和/或

  • call AllocConsole(); after SDL_init(...);
  • 调用AllocConsole();在SDL_init(...)之后;
  • use freopen("CON", stdout)
  • 使用freopen(“CON”,stdout)
  • compile without -mwindows (#undef'ing main doesn't seem to have any effect)
  • 没有-mwindows编译(#undef'ing main似乎没有任何影响)

but you should really just redirect stdout to e.g. cat, with main | cat (Always follow the rule "Don't #undef main unless you have to").

但你应该只是将stdout重定向到例如猫,主要| cat(始终遵循规则“除非必须,否则不要#undef main”)。

TL; DR

To capture stdout for MinGW, simply redirect your program to cat: main | cat. This is a hack which simply makes sure stdout and stderr don't point to nothing.
To capture both stdin and stdout, compile without -mwindows to create a Windows console application. This will open a new window if necessary.

要捕获MinGW的标准输出,只需将程序重定向到cat:main |猫。这是一个黑客,只是确保stdout和stderr不指向任何东西。要捕获stdin和stdout,请在不使用-mwindows的情况下进行编译以创建Windows控制台应用程序。如有必要,这将打开一个新窗口。

Note: It is especially important to flush output when using one of the above methods. Relying on line buffering is bad practice anyway.

注意:使用上述方法之一冲洗输出尤为重要。无论如何,依靠线缓冲是不好的做法。

#3


1  

(I couldn't post this yesterday because I didn't have enough reputation)

(我昨天不能发帖,因为我没有足够的声誉)

Ok, did a little experimenting on the lines of the batch file. My resulting and (almost) working batch file:

好的,对批处理文件的行进行了一些实验。我的结果和(几乎)工作批处理文件:

program.exe

Didn't realise it would be this simple, but still can't understand why double clicking on the program doesn't work. I said almost working because after the client connects to the server the console blanks out, so there is still an issue. So, I still would really apreciate any help with this problem.

没有意识到这将是这么简单,但仍然无法理解为什么双击该程序不起作用。我说几乎工作,因为在客户端连接到服务器后控制台空白,所以仍然存在问题。所以,我仍然会对这个问题提供任何帮助。

(End of yesterday's prospective post)

(昨天的预期结束)

(Begining of today's answer)

(开始今天的答案)

I tried Emartel's suggestions but it still didn't work. Did some testing and discovered that an infinite loop of printing a empty string was causing the issue of the blank screen after connecting the client. Fixed the loop and now it works properly, although I still have to use the batch script.

我尝试了Emartel的建议,但它仍然没有用。做了一些测试并发现打印空字符串的无限循环导致连接客户端后出现空白屏幕问题。修复了循环,现在它正常工作,虽然我仍然需要使用批处理脚本。

Would apreciate knowing if someone ever figures out why double-clicking doesn't work.

如果有人弄清楚为什么双击不起作用,我们会知道吗?

#4


0  

Two reasons:

两个原因:

  • With SDL the console is disabled. SDL uses windows, not consoles.

    使用SDL,控制台被禁用。 SDL使用的是Windows,而不是控制台。

  • SDL redirects the standard output (both cout and printf()) to a file named stdout.txt in the same folder where the *.exe is located directory.

    SDL将标准输出(cout和printf())重定向到* .exe所在目录所在的同一文件夹中名为stdout.txt的文件。

You can use:

您可以使用:

std::cout << "Hello World";

And the message will be stored in the file stdout.txt.

消息将存储在stdout.txt文件中。