Console Character Manipulation

Pages: 12
Mar 7, 2010 at 11:26am
I've been trying to create a basic console progress bar for a program I have (it calculates PI but can take a really long time), what I wanted to know is if there's anyway that I can somehow go to specific line in the console, and manipulate it, like if it looked like this:

1
2
3
44%
|0%                                          100%|
++++++++++++++++++++++

And what I'd like to do is change the 44% to whatever the current percent is. Is that even possible? And if so, how would I do it?
Mar 7, 2010 at 11:38am
Yes it's possible, but threading is the only thing that comes to mind to solve this
Mar 7, 2010 at 11:40am
How would you do it via threading? I've worked with threading in Java before, but I'm unfamiliar with how to do it in C++.
Mar 7, 2010 at 11:40am
Not really done much threading myself so I wouldn't know, but I guess you could pickup the boost library for it and work your way up from there
Mar 7, 2010 at 12:25pm
You don't need multi-threading for this. Your algorithm runs, and in every x-th iteration it changes the console progress bar. Your only problem is to make your program change the console characters in a non-stream based way (no std::cout).
I recommend to use pdcurses or ncurses for portable console manipulation.
Mar 7, 2010 at 1:24pm

Your algorithm runs, and in every x-th iteration it changes the console progress bar

I agree with R0mai .

But i did not get this part

Your only problem is to make your program change the console characters in a non-stream based way (no std::cout).
Mar 7, 2010 at 1:27pm
With cout you can't update old lines, thus you need something like the curses library as R0mai suggested
Mar 7, 2010 at 5:06pm
There is a windows API implementation of cursor movement that I remember seeing around here. But curses is definitely a better solution.
Mar 7, 2010 at 5:47pm
if he's making it windows specific there's really no reason why he couldn't/shouldn't use the WinAPI, but I agree that portability through curses is the best course if portability is at all desired.
Mar 7, 2010 at 7:03pm
http://www.google.com/search?btnI=1&q=msdn+SetConsoleCursorPosition

1
2
3
HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
COORD pos = { 10, 5 };
SetConsoleCursorPosition( hStdOut, pos );

Hope this helps.
Mar 7, 2010 at 8:00pm
Thanks for all the replies, just one last question, R0mai, you talked about pdcurses and ncurses, are they c-standard, or will I need to get them somewhere? And how would I implement them so I can #include them.

Oh, and Duoas, the only thing about the code snippet you sent me, how would I set it to the last position that I had before I moved the cursor, like to say, the very last character that was printed out to the console.
Mar 7, 2010 at 8:05pm
how would I set it to the last position that I had before I moved the cursor


The page Duoas linked to wrote:

To determine the current position of the cursor, use the GetConsoleScreenBufferInfo function.


Relevent links:
http://msdn.microsoft.com/en-us/library/ms683171(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms682093(VS.85).aspx


example:

1
2
3
4
5
6
7
8
9
10
CONSOLE_SCREEN_BUFFER_INFO buf;
GetConsoleScreenBufferInfo( STD_OUTPUT_HANDLE, &buf );

COORD oldpos = buf.dwCursorPosition;

 // move cursor to new position

 // write stuff

 // move cursor back to oldpos 
Last edited on Mar 7, 2010 at 8:06pm
Mar 7, 2010 at 8:20pm
I've implimented everything, and it shoots out only one error
1
2
1>\visual studio 2008\projects\picalc\main.cpp(43) : error C2664: 'GetConsoleScreenBufferInfo' : cannot convert parameter 1 from 'DWORD' to 'HANDLE'
1>        Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast


Any ideas? I used the exact code that you entered for me, Disch.
Mar 7, 2010 at 8:20pm
just one last question, R0mai, you talked about pdcurses and ncurses, are they c-standard, or will I need to get them somewhere? And how would I implement them so I can #include them.

pdcurses and ncurses, are libraries, you have to download them and follow the installing instructions for your specific platform.
Mar 7, 2010 at 8:21pm
Ah crap, sorry:

1
2
3
HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );

GetConsolScreenBufferInfo( hStdOut, &buf );
Mar 7, 2010 at 8:23pm
@Daenyc
Always post the code which caused the error. We can't help you otherwise.

Edit: ...whatever... :)
Last edited on Mar 7, 2010 at 8:24pm
Mar 7, 2010 at 8:31pm
Okay, it sorta worked, it throws no errors when compiling, but when I run it, it says: "Run-Time Check Failure #3 - The variable 'buf' is trying to be used without being initialized"

Here is a snippet of the implementation of the code that you guys have been sending me.

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
if(i%(percentClock/2)==0)
{
	currentPercent++;
	CONSOLE_SCREEN_BUFFER_INFO buf;
	HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
	COORD oldpos = buf.dwCursorPosition;
	if(currentPercent<10)
	{
		COORD pos = { 2, 3 };
		SetConsoleCursorPosition( hStdOut, pos );
		cout << "\b" << currentPercent;
		SetConsoleCursorPosition( hStdOut, oldpos);
	}else if(currentPercent<100)
	{
		COORD pos = {3,3};
		SetConsoleCursorPosition( hStdOut, pos );
		if(currentPercent==10)
		{
			cout << "\b" << currentPercent;
		}else
		{
			cout << "\b\b" << currentPercent;
		}
		SetConsoleCursorPosition( hStdOut, oldpos);
	}else
	{
		COORD pos = {4,3};
		SetConsoleCursorPosition( hStdOut, pos );
		cout << "\b\b" << currentPercent;
		SetConsoleCursorPosition( hStdOut, oldpos);
	}
}
Mar 7, 2010 at 8:39pm
You're never calling GetConsolScreenBufferInfo
Mar 7, 2010 at 8:43pm
Okay, just added it, don't know how that got deleted, but now it says that it doesn't know the identifier. I've #include <windows.h> Unless it's in another library.
Mar 7, 2010 at 8:49pm
blech

GetConsoleScreenBufferInfo

(I left off the 'e' in Console)
Pages: 12