Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将控制台输出数据输入命令提示符?_C++_Visual Studio 2010_Visual C++_Mfc_Console - Fatal编程技术网

C++ 如何将控制台输出数据输入命令提示符?

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()时,它不会打开新控

我有一个基于Windows的应用程序。我使它同时适用于
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;
}