C++ 如何将控制台输出数据输入命令提示符?
我有一个基于Windows的应用程序。我使它同时适用于C++ 如何将控制台输出数据输入命令提示符?,c++,visual-studio-2010,visual-c++,mfc,console,C++,Visual Studio 2010,Visual C++,Mfc,Console,我有一个基于Windows的应用程序。我使它同时适用于GUI模式和控制台模式。在GUI模式或Console模式中,我通过使用AttachConsole()将输出打印语句带到控制台来附加控制台。现在的挑战是,当我在控制台模式或从命令提示符使用控制台时,我不需要新的控制台出现。 假设在命令提示符下,我以 d:\Project path>MyApp.exe控制台模式**输入** 然后它会显示另一个控制台,因为Attachconsole()。现在,当我禁用AttachConsole()时,它不会打开新控
GUI模式
和控制台模式
。在GUI模式
或Console模式
中,我通过使用AttachConsole()
将输出打印语句带到控制台来附加控制台
。现在的挑战是,当我在控制台模式
或从命令提示符
使用控制台时,我不需要新的控制台出现。
假设在命令提示符下,我以
d:\Project path>MyApp.exe控制台模式
**输入**
然后它会显示另一个控制台,因为Attachconsole()
。现在,当我禁用AttachConsole()
时,它不会打开新控制台,也不会在命令提示符中显示输出。但我的要求是在commandprompt
中显示输出,而不是在从comamnd提示符执行时打开新控制台
Myapp.cpp
Winmain()
{
....
...
AttachConsole();
cout << "Console Attached \n";
// Some more output
}
如果你看上面的代码,我已经禁用了AttachConsole()
。现在,当我这样做的时候
d:\Project path>MyApp.exe控制台模式
**输入**
输出将以comamnd提示符显示。如下
d:\Project path > MyApp.exe consolemode **Enter**
Console Attached
....
...
d:\Project path >
请帮助我一个进程只能有一个控制台。因此,如果已经有控制台,那么AllocConsole将失败,但是如果尚未连接到父进程的控制台,则AttachConsole将成功。如果从命令提示符运行,您将已经连接到父控制台,该控制台将为cmd.exe,并且AttachConsole也将失败(除非您首先调用FreeConsole)。如果没有控制台(“GUI模式”),则AllocConsole将成功(如果您知道一个进程的PID,该进程有一个可以附加到的控制台,并且您有足够的访问权限,那么AttachConsole也将成功)。因此,您只需首先尝试分配,如果分配失败,则调用AttachConsole(-1),如果分配失败,则调用AllocConsole(或FreeConsole,然后调用AttachConsole)。注意:如果通过AllocConsole创建控制台,则不必同时调用AttachConsole(AttachConsole仅用于附加到不同的控制台,通常是不同进程的控制台) 如果您不想在“控制台模式”下使用cmd.exe控制台,可以调用FreeConsole(通过看到AllocConsole失败确定已经存在控制台后),然后AllocConsole将成功。此FreeConsole不会影响父进程的控制台 如果要使用标准输出函数(如printf或cout)向分配了AllocConsole的控制台写入,或在“GUI”模式下运行时使用scanf从控制台读取,则必须显式设置标准句柄,如下所示:
freopen("CON", "w", stdout);
freopen("CON", "w", stderr);
freopen("CON", "r", stdin);
不久前,我写了一篇关于如何做到这一点的博客文章。我知道发布链接是不受欢迎的,但我认为你会发现它很有用。有一个Visual Studio解决方案可以下载完整的示例应用程序:您应该掌握当前正在运行的窗口的控制柄并对其进行处理,这样您就不需要AllocSole了。此外,还必须找到光标所在的位置,并指定输出应写入该位置
HANDLE hStdout;
CONSOLE_SCREEN_BUFFER_INFO csbi;
void cp( HANDLE hConsole,wchar_t* output )
{
DWORD cCharsWritten;
COORD crCurr;
GetConsoleScreenBufferInfo(hStdout, &csbi);
crCurr = csbi.dwCursorPosition;
std::wstring ss;
ss=output;
if( !WriteConsoleOutputCharacter( hConsole,
ss.c_str(),
(DWORD)ss.length(),
crCurr,
&cCharsWritten ))
{
return;
}
}
int main( void )
{
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hStdout, &csbi);
function(hStdout,L"string");
return 0;
}
你能提供一些简单的示例代码来演示问题吗?@idji:我已经添加了一些输入,请检查itI的意思是可以编译和运行一些代码来演示问题。至少在您的计算机上可以这样做。我的猜测是,当您稍后创建新的console对象来附加它时,会弄乱默认输出。因此,在这种情况下,您还需要注释掉这一行。只是想澄清一下:如果您从现有控制台启动程序,并调用AttachConsole(ATTACH_PARENT_PROCESS),您会得到一个新的控制台吗?我希望AttachConsole将使用以前的控制台(如果存在)。
HANDLE hStdout;
CONSOLE_SCREEN_BUFFER_INFO csbi;
void cp( HANDLE hConsole,wchar_t* output )
{
DWORD cCharsWritten;
COORD crCurr;
GetConsoleScreenBufferInfo(hStdout, &csbi);
crCurr = csbi.dwCursorPosition;
std::wstring ss;
ss=output;
if( !WriteConsoleOutputCharacter( hConsole,
ss.c_str(),
(DWORD)ss.length(),
crCurr,
&cCharsWritten ))
{
return;
}
}
int main( void )
{
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hStdout, &csbi);
function(hStdout,L"string");
return 0;
}