how to display in cmd getting string from c++ or windows programming

Can any one help me..
I agree with Salem that you made a post which leaves something to be desired, but nonetheless I understand what you are asking.

Its very easy to do and I do it all the time. Check out AllocConsole() and FreeConsole() at MSDN. That will get you a console in a Windows GUI program. Then I believe you'll need GetStdHandle() to get an output handle for output to the console window. Then there are a handfull of console functions which can be used to write to the console, but I believe WriteConsole() is the one I use most.

Actually, that last sentence isn't completely true. Over the years and going back a long time I've mostly used C's printf() to write to the console in GUI programs where I created a console, but there are presently some issues with that that I haven't been able to resolve. Haven't been able to get it to work in any version of VStudio after VS 2008 (I think VC15).

You are likely interested in using std::cout from iostream. I can't speak to that because I'm a strange C++ programmer who doesn't like iostream and never uses it (or anything else for that matter from the C++ specific part of the C++ Standard Library).

To use the Windows Console Mode functions to print strings - or anything else for that matter, you'll need helper functions such as sprintf, swprintf, etc., to write variable output to an allocated buffer. Then you can use strlen() and WriteConsole() to output the contents of the buffer. I could provide an example I guess if you wish.
Hi @freddie1

Actual use case is running the Application.exe from cmd with admin access i'm getting one string value like "abccxxxxxx". this gets value i need to display or print in cmd immediate after the setup.exe command.

Ex: cd c:/project_1/Application.exe (command)
string value : abccxxxxxx (I'm expecting like this)

I used wprintf,printf,_wprintf functions but i'm not getting expected result.

is there any way to achieve this.


Last edited on
I'm glad you are still with us rajesh5479. I had been thinking about this issue quite a bit because it really, really bummed me out big time several years back when I moved from Visual Studio 2008 to VStudio 2015. Microsoft's fairly recent 'refactoring' of the C Runtime screwed up the code I had originally used from around 1998 to enable C runtime console functions (printf, etc.) to work in GUI programs. And in fact, for Visual Studio 2008 (vc15), I had to tweak the code to get it to work, but I DID get it to work. Microsoft broke my code once again sometime between VS 2008 and VS 2015. I expect its also broken in VS 2019. Several years back when I installed VS 2015 I sank a day or two into trying to fix my code but I failed. I'm planning to make another attempt, but I'm not sure I'll succeed. To make a very, very, long story short, the problem with using such functions as printf or std::cout for console output in programs with a GUI is that the standard input, output, and stderr handles are zeroed out before GUI initialization. Related to that, C/C++ Runtime functions sit on top of the Windows API layer (and are not the API layer itself like in *nix operating systems).

If I can get these C Runtime functions working I'll post the code here, but it may take awhile. I retired a couple years back, and only have limited time now to work on these things. That is why in my original reply to your original post I recommended you use the Windows 'Console Mode' API functions to write to a console in a GUI program. They are only slightly harder to use than printf or cout. Usage would be something like so....

pseudo code....

1
2
3
4
5
6
7
AllocConsole()
HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
wchar_t szBuffer[80];
int iWeight = 180;
int iCharsWritten=0;
wsprintf(szBuffer, L"My Name Is Fred And I Weight %d Pounds.", iWeight); 
WriteConsole(hOutput,szBuffer,wcslen(szBuffer),&iCharsWritten,NULL);


Realize, as I've alluded to above, that the internal implementation of printf or std::cout would be in terms of code such as above.

I'll post workable printf / cout code if and when I get it working.
Last edited on
I am not up on current win gui code either, but from what I recall, it was easier to make your program a console based program and add windows to it than to try to add a console to a gui program. If the above did not get you there, maybe try remaking the project this way. There is only a little to change, most of your old code will be fine, but you will have to init and fire off the gui in your console winmain section, is all.
Just to give you an idea of the code involved that I need to fix or get working with the newer versions of Microsoft's C/C++ build chain, below is my sample program that does exactly what you want, but it will only work with VC15 of Visual Studio 2008. The program creates a main GUI app window with one button on it. When you click the button the code creates a console and uses printf to write a string to the console just exactly the same as if it weren't a GUI program. Examine the code in fnWndProc_OnCommand() to see how I reinitialize the standard output handle stdout for printf's use. First AllocateConsole.h...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//Main.h
#ifndef Main_h
#define Main_h

#define IDC_BUTTON1                       1500
#define dim(x)                            (sizeof(x) / sizeof(x[0]))

struct WndEventArgs
{
 HWND                                     hWnd;
 WPARAM                                   wParam;
 LPARAM                                   lParam;
 HINSTANCE                                hIns;
};

LRESULT CALLBACK fnWndProc_OnCreate       (WndEventArgs& Wea);
LRESULT CALLBACK fnWndProc_OnCommand      (WndEventArgs& Wea);
LRESULT CALLBACK fnWndProc_OnDestroy      (WndEventArgs& Wea);

struct EVENTHANDLER
{
 unsigned int                             iMsg;
 LRESULT                                  (*fnPtr)(WndEventArgs&);
};

const EVENTHANDLER                        EventHandler[]=
{
 {WM_CREATE,                              fnWndProc_OnCreate},
 {WM_COMMAND,                             fnWndProc_OnCommand},
 {WM_DESTROY,                             fnWndProc_OnDestroy}
};
#endif 


AllocateConsole.cpp....

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// AllocateConsole.cpp
// cl AllocateConsole.cpp Kernel32.lib User32.lib Gdi32.lib /Feac1 /O1 /Os /MT /GA
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>          //contains equate _O_TEXT
#include <io.h>             //contains declare for _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT);
#include <tchar.h>
#include "AllocateConsole.h"


LRESULT CALLBACK fnWndProc_OnCreate(WndEventArgs& Wea)
{
 HWND hButton=NULL;
 
 Wea.hIns=((LPCREATESTRUCT)Wea.lParam)->hInstance;
 hButton=CreateWindow("button","Show And Write To Console",WS_CHILD|WS_VISIBLE,90,50,200,30,Wea.hWnd,(HMENU)IDC_BUTTON1,Wea.hIns,0);
 
 return 0;
}


LRESULT CALLBACK fnWndProc_OnCommand(WndEventArgs& Wea)
{
 if(LOWORD(Wea.wParam)==IDC_BUTTON1)
 {
    int hCrt         = 0;
    int iWeight      = 0;
    FILE* hf         = NULL;	
    BOOL  blnSuccess = FALSE;
    
    blnSuccess         =  AllocConsole();
    if(blnSuccess)
    { 
       hCrt            = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT);
       hf              = _fdopen( hCrt, "w" );
       __iob_func()[1] = *hf; //_iob[1]=*hf;
       iWeight         = 178;
       printf("My Name Is Fred And I Weight %u Pounds!\n",iWeight);
    }
 }
 
 return 0;
}


LRESULT CALLBACK fnWndProc_OnDestroy(WndEventArgs& Wea)
{
 FreeConsole();
 PostQuitMessage(0);
 
 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 TCHAR szClassName[]=_T("AllocateConsole");
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=0;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=NULL;                             wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=0;
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,775,575,400,190,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return (int)messages.wParam;
}


Again, this code won't work in the newer VStudio versions. Last it worked was VS 2008 far as I know. Only a very slight modification of it worked in Visual Studio 98 (vc6).
Hey Jonin!

You are exactly right! The only real difference between a console mode program and a GUI program is the link step. In the IDE of a console program one would have to go to the link properties page and add user32.lib, gdi32.lib, etc, to add GUI code. But you would start off with a console that worked right off the bat.

This business of getting the C Runtime functions to work in GUI Windows programs is a real 'nerdy' kind of thing. Its 'non-standard' in the sense that Microsoft keeps breaking the code every couple Visual Studio versions. I guess the reason I get 'torgued off' on it is that I really was proud/happy to get this working years ago with VC98. In fact, at that time my main programming language was PowerBASIC, which is a language which allows Win32 Api code exactly like C or C++, i.e., a WinMain, Window Procedure, direct Api calls, etc., and I even managed to get it working in PowerBASIC, and even cooler, I did a LoadLibrary on msvcrt.dll and declared C Runtime printf in my PowerBASIC program, and used printf in PowerBASIC exactly as my C/C++ code above does! Yea, I really 'got off' on that! Gotta be a nerd I guess!

If somebody wants to show me up, fix my code above to get it working in VS 2019. I'm not proud! I'll take your code and use it!

Fred
Last edited on
One other point about this issue and the code above.

When you open a console window in a GUI program and click the little x button to close the console window, it 'takes out' the whole process - not just the console. That's how consoles work. Its unchangeable and immutable. This is not good. If my memory serves me correctly, there are no WM_CLOSE or WM_DESTYROY message handlers in the GUI part of the process that get called. Whole process simply ends immediately. In a serious program where clean up, i.e., memory allocations/files/databases, need to be released/closed - it won't happen. Only solution I know of is to disable x button in title bar of console window. I can provide code to do that.
OK, I modified my code above to use the Windows Console Mode API instead of the C Runtime. Works perfectly, as I said it would. Here's the full code again, including AllocateConsole.h, which didn't change....

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//AllocateConsole.h
#ifndef Main_h
#define Main_h

#define IDC_BUTTON1                       1500
#define dim(x)                            (sizeof(x) / sizeof(x[0]))

struct WndEventArgs
{
 HWND                                     hWnd;
 WPARAM                                   wParam;
 LPARAM                                   lParam;
 HINSTANCE                                hIns;
};

LRESULT CALLBACK fnWndProc_OnCreate       (WndEventArgs& Wea);
LRESULT CALLBACK fnWndProc_OnCommand      (WndEventArgs& Wea);
LRESULT CALLBACK fnWndProc_OnDestroy      (WndEventArgs& Wea);

struct EVENTHANDLER
{
 unsigned int                             iMsg;
 LRESULT                                  (*fnPtr)(WndEventArgs&);
};

const EVENTHANDLER                        EventHandler[]=
{
 {WM_CREATE,                              fnWndProc_OnCreate},
 {WM_COMMAND,                             fnWndProc_OnCommand},
 {WM_DESTROY,                             fnWndProc_OnDestroy}
};
#endif 


Now AllocateConsole1.cpp...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// AllocateConsole1.cpp
// cl AllocateConsole1.cpp Kernel32.lib User32.lib Gdi32.lib /Feac2 /O1 /Os /MT /GA
// g++ AllocateConsole1.cpp -oac2.exe -mwindows -m64 -s -Os
#ifndef UNICODE
   #define UNICODE
#endif
#ifndef _UNICODE   
   #define _UNICODE
#endif   
#include <windows.h>
#include <stdio.h>
#include "AllocateConsole.h"


LRESULT CALLBACK fnWndProc_OnCreate(WndEventArgs& Wea)
{
 HWND hButton=NULL;
 
 Wea.hIns=((LPCREATESTRUCT)Wea.lParam)->hInstance;
 hButton=CreateWindow(L"button",L"Show And Write To Console",WS_CHILD|WS_VISIBLE,90,50,200,30,Wea.hWnd,(HMENU)IDC_BUTTON1,Wea.hIns,0);
 
 return 0;
}


LRESULT CALLBACK fnWndProc_OnCommand(WndEventArgs& Wea)
{
 if(LOWORD(Wea.wParam)==IDC_BUTTON1)
 {
    HMENU   hSysMenu        = NULL;
    HANDLE  hStdOut         = NULL;
    int     iWeight         = 178;
    DWORD   dwCharsWritten  = 0;
    BOOL    blnSuccess      = FALSE;
    wchar_t szBuffer[80];
    
    blnSuccess=AllocConsole();
    SetWindowLongPtr(Wea.hWnd,0,(LONG_PTR)blnSuccess);    // Store success/failure of AllocConsole call at offset 0 of WNDCLASSEX::cbWndExtra bytes
    if(blnSuccess)
    { 
       hSysMenu=GetSystemMenu(GetConsoleWindow(),0);
       DeleteMenu(hSysMenu,6,MF_BYPOSITION);    
       hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
       wsprintf(szBuffer,L"My Name Is Fred And I Weight %d Pounds.\n",iWeight);
       WriteConsole(hStdOut,szBuffer,wcslen(szBuffer),&dwCharsWritten,NULL);
    }   
 }
 
 return 0;
}


LRESULT CALLBACK fnWndProc_OnDestroy(WndEventArgs& Wea)
{
 if(GetWindowLongPtr(Wea.hWnd,0))
    FreeConsole();
 PostQuitMessage(0);
 
 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 wchar_t szClassName[]=L"AllocateConsole";
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=0;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=NULL;                             wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=sizeof(void*);
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,775,575,400,190,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return (int)messages.wParam;
}


Note I tested it with my old version of Visual Studio 2008 on this old Dell M6500 laptop running 64 bit Windows 7. But I have high confidence it will work unchanged on Windows 10 with Visual Studio 2019. I'll check it out later on my newer laptop, but wanted to post it now. Note further I added code to disable the x button of the console window so clicking it won't take the whole process out.

By the way, I have the command line string above for building with GCC, and it worked without modification, but its also an older version of GCC - TDM-GCC 4.8 I think. Yea, I know its old, but so am I.
Last edited on
Hi @freddie1 & Jonnin,

Thanks both of you for valuable info.

but I want string value display

string1 = L"rajesh";
wsprintf(szBuffer, L"String value : %s ", string1);
WriteConsole(hStdOut, szBuffer, wcslen(szBuffer), &iCharsWritten ,NULL);

i have written code like above but value is not displaying in console ,it's displaying like below
String value :
String value : rajesh (expecting)
Last edited on
What type of variable/object is string1? The C OOP based Win Api doesn't know anything about C++ Std. Library string objects - just null terminated char buffers. If string1 is a C++ Standard Library string object, then you need to use string::cstr(), i.e.,...

string1.cstr()

Or is it c_str(). I forget. I use my own String Class - not the one in std lib.
Oh! One more thing....

If string1 is a std::string, then I believe what you are looking for is a character buffer string concatenation operation. In szBuffer you have this....

"String Value :"

To that you need to concatenate whatever characters are in string1. So it would be like so....

wcscat(szBuffer, string1.c_str());

If, as I said, string1 is a C++ std::string, then that should do it for you. Unless it doesn't, of course! :)

added later....

I assume you are using std::string. So I'd do...

char szBuffer[80];
strcat(szBuffer, string1.c_str());
Last edited on
Just wanted to add.....

...I figured out how to use printf with Visual Studio 2019's build chain. Is anyone interested? If you recall, in my previous posts I stated that I first figured it out using VC6 from Visual Studio 98 circa 1998 or so. My policy is to get a new version of Visual Studio every 10 years, whether I need it or not. So when I got my VStudio 2008 I found Microsoft broke my code due to changes in stdio.h and associated LIBCMT.LIB. So I fixed it. Now, Microsoft broke it again, so I fixed it again. This time though, the fix will be permanent. Anyone interested in seeing the details?
Registered users can post here. Sign in or register to post.