So I have a GUI program and for some reason it does not let me debug using printf().
When I use printf(), it does not go to the Visual Studio debugger for some reason.
Anyways, I wanted to make my own separate window that opens up when the GUI opens up,
and basically be able to feed information into that console and talk to it.
For example:
void talk(std::string info){
//Add the value of info to the next line in the console
}
Anyone know how to do this?
Basically create a command line and talk to it so I can see output:
CommandLine c;
c.talk("hey!");
You can create a console using AllocConsole to create a console, then write to that explicitly (there are a few methods, GetStdHandle and file write will work). You can also use OutputDebugString to write to the VS output window.
void makeConsole()
{
AllocConsole();
console = GetStdHandle(STD_OUTPUT_HANDLE);
}
void talk(std::string info)
{
WriteFile(console, info.c_str(), info.length()); // To console
OutputDebugString(info.c_str()); // To output window
}
(pseudo-code, functions may not be quite right)
Edit:
If you're writing to the console only through your talk function, this will work fine. If you're using printf/cout throughout your code, you definitely want to use Ben's method (much simpler to use repeatedly).
#peachykeen has half the solution. If you want to make printf and cout work, try this:
AllocConsole();
freopen("CONOUT$", "w", stdout);
Related
This question already has answers here:
How and why does QuickEdit mode in Command Prompt freeze applications?
(2 answers)
Closed 6 years ago.
for an application of mine I have been playing around with the Windows API a bit, namely creating a very small wrapper for window functionality. Since I like to have console output as well, I created a console via AllocConsole(). I then noticed that highlighting text in this console (like if you want to copy something) 'freezes' the open window, ie. no messages will be processed, it is not click- or closable. Message loop and wndProc are both standard.
Two questions: is that intended/documented behaviour (I couldn't find anything about it) and if yes, is there a way to disable it? It's kind of annoying.
Thanks in advance
EDIT: as requested, the console creation code:
FILE *conOut = NULL;
FILE *conIn = NULL;
if (::AllocConsole())
{
::freopen_s(&conIn, "CONOUT$", "r", stdin);
::freopen_s(&conOut, "CONOUT$", "w", stdout);
// ...
if (conOut != NULL)
::fclose(conOut);
if (conIn != NULL)
::fclose(conIn);
::FreeConsole();
}
I created a test Win32 application with a basic Win32 project. I added a simple class to handle the console creation and tested two scenarios. What I found was the console window output will stop as if the thread generating the output is suspended when an Edit->Mark is done until the Mark is completed with a Copy or canceled.
The two scenarios tested with the Win32 application were: (1) printing to console window in a separate thread and (2) printing to console window in the main window message handling logic.
The particulars of the test program and details of the two scenarios tested are as follows.
Console.h
#pragma once
#include <stdio.h>
class CConsole
{
public:
CConsole(void);
~CConsole(void);
int Create(void);
public:
FILE *m_conOut;
FILE *m_conIn;
};
Console.cpp
#include "StdAfx.h"
#include "Console.h"
CConsole::CConsole(void)
{
}
CConsole::~CConsole(void)
{
}
int CConsole::Create(void)
{
if (::AllocConsole())
{
::freopen_s(&m_conIn, "CONIN$", "r", stdin);
::freopen_s(&m_conOut, "CONOUT$", "w", stdout);
}
return 0;
}
In the main file at the near the top where the Win32 project wizard put some global variables, I added an additional global variable CConsole myConsole; for my console and then I added a bit further down a simple function that is the target of a _beginthreadex(). The function looks like:
unsigned __stdcall myThread( void *x )
{
HWND hWnd = (HWND)x;
// allow for two different test scenarios depending on whether the
// SendMessage() is commented out or the fprintf() is commented out.
// if SendMessage() is live then the main window will write to the console window
// if fprintf() is live then this thread will write to the console window.
for (int i = 0; i < 50; i++) {
// SendMessage (hWnd, WM_USER, i, 0); // send a message to main window to request print
fprintf (myConsole.m_conOut, "This is line %d\n", i); // print from this thread
Sleep (1000);
}
return 0;
}
In the InitInstance(HINSTANCE hInstance, int nCmdShow) just before the return statement, I added the following two lines of code:
myConsole.Create();
_beginthreadex (NULL, 0, myThread, hWnd, 0, NULL);
Finally in the main message loop that handles the messages for the main window I added an additional message target:
case WM_USER:
fprintf (myConsole.m_conOut, "This is line %d\n", wParam);
break;
I then tried two different experiments by commenting out one of the two lines in my function that is the target of the _beginthreadex().
One was to print to the console window using fprintf() within that thread. The second test case was to send a message of WM_USER to the main window and ask it to use fprintf() to print to the console window.
What I found was that with the printing being done by the thread then I observed the following behavior when I used the Edit->Mark to begin the procedure of marking text to copy:
the main window was responsive to menu choices
the console window output stopped
when I cleared the mark or copied text, console window output resumed
The behavior was as if the thread writing to the console window was suspended until the Mark and Copy procedure was completed.
When the printing was done by the main window's message loop when handling the WM_USER message then I observed the following behavior when I used the Edit->Mark to begin the procedure of marking text to copy:
the main window was unresponsive to menu choices
the console window output stopped
when I cleared the mark or copied text, main window responsiveness returned as did console output
For some additional information about the Console Window Subsystem see Consoles. For a bit of information about the technology see WinEventProc Callback Function along with SetWinEventHook which describes this functionality to some extent as well as What Are WinEvents? and In-Context Hook Function Precautions.
See also Console Window Host in the book Windows Internals for a brief overview of the Console Window Subsystem.
And see Windows 7 / Windows Server 2008 R2: Console Host for an introduction to the architecture changes.
Finally The Console Host Process in Windows 7 from the book Inside Windows Debugging shows how to "discover the various layers involved in the printf sequence".
It may be possible to use the Console functions at a lower level to directly interface with the Console Window Subsystem in order to prevent the freezing of the thread which is doing I/O to the console window.
I have read and tried many solutions and nothing solved my problem.
I am generating a dll out of c++ code and want to display the printf() or the std::cout inside of a console window. For testing I just create a .exe out of the c++ code but that is not solving the problem!
I know that system("Pause") is a bad habit, but this is just an easy way to get the same problem. Instead of calling system("Pause") I'm doing a system()-call that is calling the cl.exe and is compiling a dll out of a .c file(Like: system("cl...). The generation of the dll out of the other c file is working without any problems. But after I called the system function for compiling the dll file the printf and std::out are not displaying the right text in the console window.
here is my example code that is screwing up the display of the right characters:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
AllocConsole();
freopen("CONOUT$", "w", stdout);
std::cout << "Everything works fine\n";
// Calling the cl.exe by cmd...
system("Pause");
std::cout << "now its strewd up the newline is not working\n" << std::endl;
FreeConsole();
return 0;
}
Here is a picture of the output:
I tried the fflush before and after calling the system().
So here are my further thoughts:
Could I call the cl.exe by a CreateProcess and would that solve my problem?And when yes, how will I do that and to implement the environment variables out of the batch vcvars32.bat. So I want to create a dll out of a .c located both in the same folder.
Or could write a batch file that is calling the whole cl.exe and vcvars32.bat file process.
Or is there another way to display the values out of a dll instead of calling AllocConsole()?
I hope you can help me maybe I'm missing something!
So in order to try these error on my laptop (because I'm travelling today) I set up the same code at my laptop. Because I forgot to uncheck Security Development Lifecycle (SDL) checks there was an error when calling freopen("CONOUT$", "w", stdout); .Because the error message at building the code inside of visual studio 2015 was:
Severity Code Description Project File Line
Error C4996 'freopen': This function or variable may be unsafe. Consider using freopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. ConsoleApplication1 c:\users\noxious\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp 12
I searched for the function freopen_s and exact at a example of freopen_s I saw the following code Outputting Unicode to Allocated Console Issue:
freopen_s(&stream, "CONOUT$", "w+t", stdout);
I tried this one and acually my problem was solved! BUT it wasn't the freopen_s that solved the problem it was just the inside of it "w+t" so I looked it up and saw that w+ is refering to the following type of access cstdio: freopen:
"w+"
Create an empty file for reading and writing. If a file with the same name already exists its content is erased before it is opened.
So I tried a few combinations and got this resulst:
wt not working
w+t working (but the t is always standard even if you use w+ is the same as w+t
w+ working
So I think I have just to setup an empty file for reading and writing! I will looking further deep into that because I'm not quite sure what is the difference and if it is still solving the problem when using the dll instead of the exe file!
Hope this might help some other people who are trying to solve same errors! But just a "+" was delaying my work now for more than one day!
Edit 5.10.2015:
So I tested this function with the "w+" instead of "w" and it fixed my problem!Even using a dll instead of a generated exe!
It looks like the process is changing the output codepage on the console, then not changing it back when it's done. Not sure why this would happen, but if that's the cause, it should be sufficient to save and restore the codepage:
AllocConsole();
freopen("CONOUT$", "w", stdout);
std::cout << "Everything works fine\n";
// Calling the cl.exe by cmd...
UINT codepage = GetConsoleOutputCP();
system("Pause");
SetConsoleOutputCP(codepage);
std::cout << "Should work now." << std::endl;
FreeConsole();
return 0;
BTW, it might also be screwing up the input codepage. You can use GetConsoleCP() and SetConsoleCP() for that.
I have an MFC application that generates some reports and shows the same in the GUI.
I have a requirement of running it as a console application, when passed with certain commandline argument.
In the console mode it will generate the reports/errors in standard output/error and I should be able to redirect the same to any file.
For Ex.
C:/temp MyApp.exe --console > report.txt should run my exe in console mode and redirect all the output to a text file.
But if I run it without any console argument, it should be like a default MFC application.
To achieve my requirement, so far I have done is, changed the Linker > System > Subsytem from Windows to Console and added WinMainCRTStartup at
Linker > Advanced > Entry Point
So now my app works fine when I run it with --console parameter from console/batch files.
But when I run it directly, it still opens a cmd window (of course because it is now a console application). However, I am using FreeConsole() method to get rid of it but it still flashes for a brief second.
So I am just curious if there is a way to get rid of it completely, either by deciding the application's subsytem at run time or any other trick?
Any suggestion will be appreciated.
I'd suggest to keep your GUI application with the windows subsystem.
At the very beginning, when parsing command line, instead of creating the GUI windows (MFC inistialisation), you could create a console or attach with AttachConsole()
As a proof of concept, here how it could look like (for example in CxxxApp::InitInstance()):
... // init code but before the the CMainFrame is created
if(...) { // suppose you want to go to the console
if (! AttachConsole(ATTACH_PARENT_PROCESS)) // try to hijack existing console of command line
AllocConsole(); // or create your own.
DWORD nw,nr; // demo with windows native console i/o
char buff[32];
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), L"Who are you ? ", 14, &nw, NULL);
ReadConsoleA(GetStdHandle(STD_INPUT_HANDLE), buff, sizeof(buff), &nr, NULL);
WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), "Hello ", 6, &nw, NULL);
WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), buff, nr, &nw, NULL);
ReadConsoleA(GetStdHandle(STD_INPUT_HANDLE), buff, 1, &nr, NULL);
...
}
If you want to use C++ cin/cout, additional work is however needed. This other SO question addresses for example the redirecting of cout.
I'm using someones library that printf's out an error message when a connection to a device is unsuccessful.
The library code prints out nothing when a connection is successful.
I periodically check (loop & sleep) to see if a device is connected but I only want to print out when it is connected.
At the moment I get something like:
Waiting for connection... (<-- My print)
Error
Error
Error
Error
Error
Connection successful (<-- My print)
What I want is:
Waiting for connection... (<-- My print)
Connection successful (<-- My print)
How can I programatically ignore a printf?
N.b. I found a similar question Programmatically Ignore Cout but that solution did not work for printf.
I am using Windows.
Can anyone help? (c/c++ novice)
Have you tried something like (before establishing connection):
FILE * myout = stdout;
stdout = fopen ("standard-output-file", "w");
To print something to output you could use then:
fprintf(myout, "format", ...);
Edit: Remember to close the file descriptor afterwards:
fclose(myout);
I was able to get this working under Linux the following way
#include <cstdio>
using namespace std;
int main() {
printf("Start\n");
freopen("/dev/null", "w", stdout);
printf("middle\n");
freopen("/dev/stdin", "w", stdout); // really stdin here!
printf("End\n");
return 0;
}
Under Windows I think there are other names for files (nul and con maybe).
However, this seems to be completely unportable, and, what's worse, this will prevent the users from redirecting your program output to a file, because I explicitly reopen /dev/stdin. There are suggestions that you can use /dev/fd/1 instead of /dev/stdin to mitigate the latter problem, but I have not tested it.
It seems that there is no reliable way, see, e.g. http://c-faq.com/stdio/undofreopen.html
I don't know the absolute solution, but you'll need to use:
freopen("conout$", "w", stderr);
Or something similar, but with "conout$" pseudo-file, which I believe is same as /dev/stdout on Linux.
You may have to use GetStdHandle, AttachConsole etc.
If you are using c++11 and above you can use a simple variadic template without much coding so this overloads printf for all cases and the original one never gets called
template <typename ...Args>
void printf(Args... ...)
{
}
I have a lot of C++ programs that compile with Visual Studio 2005. They're mostly small server modules that run in console windows. Anyway, the problem I'm running into is that text can only be displayed to either the console window or a log file but not both. Each program has a command line option to specify the log file. Here is the function that I call to redirect stdout and stderr to a file.
void consoleobj::setstdouterr(const stringobj& printstr)
{
#if !defined(_WIN32_WCE)
freopen(printstr.c_str(),"w",stdout);
#ifdef _MSC_VER
::SetStdHandle(STD_ERROR_HANDLE,GetStdHandle(STD_OUTPUT_HANDLE));
#endif
#endif
// make log msgs flush to log file(cout does this(on \n?), printf doesn't)
//now if both redir to same log file, msgs should be in right order
setvbuf(stdout, NULL, _IONBF, 0); //no buffering
setvbuf(stderr, NULL, _IONBF, 0); //no buffering
}//end method setstdouterr
Is there any way to set things up so stdout and stderr are written to both the console window and an optional log file simultaneously? I've seen code that redirects cout or a wrapper function, but our print statements all use printf and I'd prefer using a function similar to the one in our consoleobj library to set this up if possible. Thanks!
Instead of implement this functionality in your code.
You can use the well known utility tee in Unix.
There is a Windows version of it called wtee.exe.
C:\> programm | wtee log.txt