Update and multiple console windows - c++

I want to write a simple c++/c console app, to show my process 1% 2%.
for now, i print it line by line like
finished 1%
finished 2%
and etc
How can I just update percentage x% without printing a new line?
Also, I want to open two console windows one show messages one show the process as above. How do I open another console window?

On most-all terminals, you can print the ASCII carriage return '\r' (value 13 decimal) to return the cursor to the left of the current line, allowing you to overwrite the previous value. Or, you can send backspaces ('\b', ASCII 8) to move a single character left. Neither will automatically remove content already displayed, but you can always overwrite anything you no longer want to see with some spaces. Alternatively, you can use control codes supported by your particular console (e.g. vt100, vt220...), which will probably have more advanced features such as "clear-to-end-of-line". Many libraries are available to detect the terminal type and use codes it supports, or synthesize advanced operations from many simpler ones where necessary: on Linux and UNIX, the ncurses library is a good choice.
C++ has no concept of console windows. Opening a second window depends a lot on the operating system you're using, and perhaps the graphics library, neither of which you specified. On any OS though, you can have your application write some messages into a file, then inspect that file from another window that you open yourself. On Linux/UNIX, the utility "less" is great for inspecting log files - as well as showing you the contents at the time you ran less, you can ask it to "follow" new data as it is written into the file.

On windows you can move the cursor to any location on the screen, then start printing from there:
COORD c;
c.X = x; c.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
Of course, you need to include windows.h

You can update your progress message in several ways. You can print out backspace characters to move the cursor to the left and then write over the old output. If your console supports ANSI escape sequences, you can use an escape sequence to blank out the line and re-draw it.
The best technique to use will probably depend on the console you are using (different consoles support different things). What platform are you using, and what console?

It seems that you're talking about Windows console apps.
Each Windows process is associated with at most one console window.
It you want two console windows then you can start another process and pipe output to it, or communicate with it via sockets or Windows "mailslots" or whatever.

Related

How to get printed characters of Linux console at given position in C++ (or C)?

Suppose my whole screen (console) is filled with some text (e.g. printed through std::cout). How can I get some characters of this console output, e.g. in the center of screen?
In Windows I can get characters of console through ReadConsoleOutputCharacter function.
But how to do same thing in Linux (inside C++ (or C) code)?
Is there any easy way to do this without using extra huge libraries like ncurses? Maybe there are some standard Linux kernel sys-call functions to achieve this task?
I need to get console text of current running program. I.e. if inside my program I printed some text, later inside this same program I want to read parts of this printed to console text.

Prevent mixing of console output and written text

I have a C++ console application that prints some output constantly while it also accepts commands (using std::cin) from the user - output and input happen in separate threads.
If I write a text while some output appears the written text is mixed with application output. How can I prevent this behaviour?
To solve this problem, I need to display the program one line above the line where the text is typed. I'd inspire myself in Minecraft Bukkit server's solution - however I need the same for C++.
Assuming you want the output to appear while things are being typed, you'll need some screen control facilities to have the output go somewhere different than the input area. If I were tasked to implement something like this writing to a terminal I would refresh my ncurses experience. I realize you are on a Windows console and I have no idea if the Windows console is capable of the screen control needed to make it happen.
You can possibly tie custom stream buffers into std::cin and std::cout using the curses functionality under the hood but it may not be worth it. In any case, it isn't entirely trivial.
There's a windows port of ncurses called pdcurses. But if you are using visual studio there's a simple function provided called SetConsoleCursorPosition()

Echo characters in istream to an unusual "device"

I want to make a version of cin that works in a graphics display window (it's SDL, but I don't think that matters here): that is, when you type, the characters echo into that window rather than the console window. The solution should be cross-platform.
I have this page to tell me how to get characters NOT to echo to the console window: Reading a password from std::cin
...but what I don't know how to do is to make the characters echo on the new graphics display window.
One thing I could do is intercept keyboard events, and if one happens, print the character. But this wouldn't perfectly echo the actual behavior of the istream buffer, because of repeating keys, backspace, enter, tab, and also the real behavior of cin in that if you are typing before C++ gets to the cin, it will put that stuff you typed on the screen at that point.
I think this echoing is done inside the call to _read (read in the Unix world), and that I'm not sure how to access.
TIA.
The behaviors you're talking about are not done by cin nor read() syscall; buffering and processing of special character is done by the terminal emulator and the shell.
You do need to intercept key events and implement these yourself. Alternatively, some terminal emulators (e.g. VTE widget in Gnome) were designed so they can be embedded into another program. You might want to look at that option.
Considering your application is running in a window you shouldn't read input from the console . It's probably possible but you'll have to switch to the terminal window from where you started the window each time you want to input text. If you take this route you need to disable tty echo: http://man7.org/tlpi/code/online/dist/tty/no_echo.c.html (for Linux). Check out http://www.cplusplus.com/forum/general/12256/ for some solutions for Windows too. I don't think there is a solution that works for both so you'll need to bury some #ifdef's in some utility functions.
Since you're using SDL you should probably use SDL's input functions.
Check out http://www.libsdl.org/docs/html/guideinputkeyboard.html
And, more specific to your needs: http://wiki.libsdl.org/moin.fcg/Tutorials/TextInput

How do I output to the console, and overwrite text without clearing the screen and re-writing everything?

Like when using aircrack-ng, or any program that has tables of data that constantly update.
=\
It depends somewhat on the system, and above all, how much you want to overwrite. For a lot of simply programs, outputting '\r' will do the trick: it will return the cursor to the start of the line (on almost all consoles), and you can overwrite the line. (I've used this in the past for continuously updated progress reports: n records processed, for example. Just be sure to not output a '\n' until you're ready.
For anything more complex, the usual solution is the curses library. It should be present on most Unix (sometimes under the name ncurses), and there's a port of ncurses to Windows as well. (The generic name of the library, and its name under traditional Unix, is curses; ncurses is a GPL implementation the library.)

Async Console Output

I have a problem with my application win32 console.
The console is used to give commands to my application. However, at the same time it is used to output log messages which mostly comes from asynchronous threads. This becomes a problem when the user tries to write some input and simultaneously an async log message is printed, thus thrashing the display of the users input.
I would like to have some advice in regards to how to handle such a situtation?
Is it possible for example to dedicate the last line in the console to input, similarly to how it looks in the in-game consoles for some games?
You can use SetConsoleMode to disable input echo and line editing mode. You can then echo back input whenever your program is ready to do so. Note that this means you will need to implement things like backspace manually. And don't forget to reset the mode back when you're done with the console!
This is possible using the Console API, but it involves quite a bit of work and all the threads that use the console will have to cooperate by calling your output method rather than directly calling the Console API functions or the runtime library output functions.
The basic idea is to have your common output function write to the console screen buffer, and scroll the buffer in code rather than letting the text flow onto the last line and scroll automatically. As I recall, you'll have to parse the output for newlines and other control characters, and handle them correctly.
You might be able to get away with using "cooked" console input on the last line, although in doing so you risk problems if the user enters more text than will fit on a single line. Also, the user hitting Enter at the end of the line might cause it to scroll up. Probably best in this situation to use raw console input.
You'll want to become very familiar with Windows consoles.
Any time you have asyncronous threads trying to update the same device at once, you are going to have issues like this unless something synchronizes them.
If you have access to everyone's source code, the thing to do would probably be to create some kind of sync object that every task must use to access the console (semaphore, etc).