C++ changing output on console - c++

What is the easiest way to display changing numbers in the console? I have a normal command line program in C++ which uses cout, but I'd like to display a percentage number representing the progress which counts up to 100 without printing a new line. How is that done? (If it matters: I'm on Windows 7)

When I’ve needed that I have just output a carriage return character, in C++ \r.
Remember to flush the output each time, e.g.
cout << "\r" << x << "% completed. " << flush;
The spaces at the end to clear previous output on the line in case of Microsoft-like fluctuating progress.

Use the backspace character.
cout << "10%";
// ...
cout << "\b\b\b20%";

I normally place a carriage return after the progress information. That way, any other output will appear normal (as long as it has enough characters in the line to completely overwrite the progress info).
cerr<<percentage<<"% \r";
By the way, I prefer to use cerr instead of cout for this kind of status/diagnostic information so that cout can be reserved for real content. This way you can redirect the normal program output to a file and still see the progress in the console. Also, with cerr, you don't have to use "flush".

Related

In place counter for C++ output

I'd like to format the output of my program to print a number (index) then some text, and the number incriments as the program progresses. I'm using CLion, but I'd be interested to know if any solutions are 'universal'.
I've experiemted with flushing the output and system CLS:
cout << i << ". has been checked" << flush;
cout << system ("CLS");
in a few different configurations but I get the feeling this is not the way.
Assuming that the vertical position of the output never changes, use a carriage return character (\r) for this.
std::cout << "\r" << i << ". has been checked";
The \r just sets the position of the cursor to the beginning of the line.
If this doesn't do what you want, or you are outputting text after writing out i, then you need a more platform specific solution; move/wmove with ncurses on Linux and SetConsoleCursorPosition on Windows, for example.
Formally, there's no answer, but quite a few systems support \b for backspace.
It's a good programming exercise to try this - remember that you need to backspace each digit that's been printed. So when you go from 99 to 100, you need \b\b. And if you increment by varying steps (e.g. for "bytes downloaded") you need to keep track of how many digits are already on the screen.

How do I rewrite a line of text in a console project? c++

I'm working on a c++ console project and i would like to show a percentage without making a new line each time (so that the window doesn't get clogged with thousands of lines).
Is there a way of removing the last line that was printed or something to say that the next time that i output a line it should replace the current line?
You can use a \r (carriage return) to return the cursor to the beginning of the line:
This works on windows and Linux.
From: Erase the current printed console line
You could alternatively use a series of backspaces.
string str="Hello!";
cout << str;
cout << string(str.length(),'\b');
cout << "Hello again!";
From: http://www.cplusplus.com/forum/unices/25744/
Maybe mark as duplicate? I am really not sure how.
A simple example that I tested on Linux would be:
std::cout << "Some text to display..." << "\t\r" << std::flush;
Here the \t adds a tabulation to handle slightly varying string lengths and \r sends the cursor back at the start of the line (as mentioned in other answers).
std::flush is required to guarantee that the line is displayed without jumping to the next line.
This is very platform-dependent and terminal-dependent. But, you may want to look at ncurses for a start: http://linux.die.net/man/3/ncurses
For Windows: How can I overwrite the same portion of the console in a Windows native C++ console app, without using a 3rd Party library?
For Linux: https://unix.stackexchange.com/questions/43075/how-to-change-the-contents-of-a-line-on-the-terminal-as-opposed-to-writing-a-new

Line spacing after endl and cout?

I noticed that in the following code:
cout << "Please enter your number: ";
cin >> Number;
cout << "Is this spaced";
The output in the command window for C++ automatically puts "Is this spaced" in the next line. It spaces whatever is after the cin line without needing to use the stream manipulator (why is this called a stream manipulator?) endl. Whereas if I just have the code:
cout << "Please enter your number: ";
cout << "Is this spaced";
It won't automatically space the line with "Is this spaced". Instead both lines are joined up. I am curious to know why this is the case because I always thought that you need endl in order to create a new line of space.
Thanks!
cout << "Please enter your number: ";
cin >> Number;
cout << "Is this spaced";
There's more to this than meets the eye. std::cout and std::cin are - by default - tied streams. That means that std::cout is automatically flushed (i.e. any pending output flushed from any buffers inside your program out to the operating system) whenever std::cin is asked for input. That's why you can be sure to see "Please enter your number: " before the program pauses to wait for you to type. Of course, in most Operating Systems you can start typing before the program's waiting - it will echo it to the terminal and remember it to provide to std::cin later: that's also what happens when you invoke a program with a pipeline such as:
echo "123" | the_program
The input's available when the_program starts running, but sits there for cin >> Number; to attempt parsing. In this case though, there's no keyboard input for the terminal program to echo, and hence the "123\n" sequence isn't echoed to the screen between your two lines of output - without that newline "\n" your output will all appear on one line.
If you want to read from the keyboard without the keyboard input moving the cursor to the next line, you'd be best off using ncurses or some similar library. The libraries can use escape sequences appropriate to your terminal (if available) to reposition the cursor to your liking. It may be practical to code that up yourself if you have a very limited range of terminals to support (e.g. just xterm-compatible ones, VT220, or Windows command shells). It's also generally possible to suppress the printing of keyboard input, but then the user couldn't see themselves type the digits. Another option is to set the terminal to an input mode supporting character-by-character input reading (some terminals default to line-by-line so you can't see characters until return is pressed) - combining that with the suppressed echo above your program can print digits as they're typed, but not print the newline.
Separately, it's good practice to end your program's output with a newline, as some invocation environments won't show the final line otherwise. And, it's somewhat contentious but IMHO best practice not to use std::endl when you don't need to flush the output - just use \n and let the C++ iostream library buffer multiple lines and write them in efficiently sized chunks to the operating system.
Explanation of flushing
Say you have a program like this:
std::string h = "hello ";
std::string w = "world";
std::cout << h;
std::cout << w << '\n';
At some stage, the program needs to tell the Operating System (Linux, Windows etc.) about the text to be printed, letting it send it to a shell/cmd prompt (which might send it on to the screen and put it in buffers for scrollbars etc.), a file or whatever. In the grand scheme of things, it's slow for the program to tell the operating system to do this kind of thing, so the program as a whole will work faster if it remembers "hello ", adds "world" and \n (a newline) to it, then sends "hello world\n" to the operating system all at once. That intra-program storage and concatenation of data is called buffering, and the act of writing data from the buffer to the Operating System is called flushing.
By default cin ends reading stream when it receives a newline which also adds a new line.
When you use cin (std::cin) with the terminal, you often have to press enter to tell the terminal "hey, my input is done."
Enter is also translated as a newline, so it's sticking what is essentially a std::endl because you pressed Enter.
In many cases, you can use the backspace character \b to backtrack the console's current writing. It may work for you to try std::cout << '\b': it happened to backtrack in my terminal (Windows).

How can I use cin and cout at same time without interrupt?

I'm writing a win32 console application, who has two thread, one keep using cout to write something to console, and the other keep using cin to try get some input. Both works well, I haven't got lose of data, except that it's not beautiful...Sometimes while I'm entering something the other thread cout something out and those two things hold together. Is there anyway I can get them seperate? If there's noway to do it I have to open a window and redirect the cout stream to it, which I really don't want to do...
Make sure you are receiving the input character by character. Then whenever you need to output something start by moving the output cursor the the start of the current line with a carriage return '\r'
Then make sure your output overwrites the current input by padding it with spaces if necessary.
Finally print a line feed to start a new line and rewrite your current input
std::cout << "\r" << output << padding << "\n" << currentinput;

Strange stdout behavior

I'm currently writing a socket program in C++ and I've stumbled across very strange behavior when trying to write to the console (a required task), for some reason.
cout << themsg[0] << themsg[1] << endl;
cout << "Phase 3: Supernode sent the message " << themsg[0] << " on dynamic port number " << themsg[1] << endl;
themsg[0] is the string "User#2:What's up Dick?"
themsg[1] is the string "39416"
The first line should write "User#2:What's up Dick?" to the console, followed by "39416".
The second line should print "Phase 3: Supernode sent the message User#2:What's up Dick? on dynamic port number 39416"
The console output reads as follows:
394162:What's up Dick?
on dynamic port number 39416essage User#2:What's up Dick?
I know that themsg[0] and themsg[1] are correct because I wrote their values to a file for verification. It surely has to be some weird stdout issue.
For the first line it appears the 5 characters of themsg[1] overwrite the first five characters of themsg[0]. For the second line, it appears that the first two parameters for cout are ignored, and then there is a message fragment appended.
If anyone can help, I would really appreciate it. I tried using flush() but to no avail. I'm not really sure how the output buffer works, so I'm really lost with this.
You probably have a carriage return symbol, \r, at the end of themsg[0]. I can reproduce the behavior with the following program on Linux:
int main()
{
std::cout << "User#2: what's up?\r" << "39416" << std::endl;
}
The \r, when not followed by \n, has the effect of returning the virtual "carriage" of the terminal to the beginning of the line, so the next print will overwrite what was already there. You won't see this showing up in a file, though, as the file will just contain both strings including the CR.
Strip off the \r before printing.
I suspect the problem is in your themes variable. I tested your exact setup - and, with proper values, it works correctly. However I then tested the same setup but appended \r to the end of themsg[1] and themsg[2] - and got exactly your behaviour. As your string themsg[1] is coming from the network, it probably has line ending included - and from a different operating system (e.g. UNIX vs Windows) - this is converted to a carriage return without the line feed - resulting in the behaviour you're seeing.