I am creating a guessing game for two players. I first want a user to enter a number, which is intended to be secret. In order to keep it secret, I want to erase whatever the user has entered to cin last. I am trying to move the cursor back and insert a blank space where the user has entered a number. I am attempting to use cout << "\b" << "\b" << "\b" << " " as of right now, which you can see in my loop below.
here is my code so far:
do{ //initial do-while loop to begin game
int secretNumber = 0; //initilized to a default value of 0 to make the compiler happy
do {
//prompt user for input
cout << "Please choose a secret number between 1 and 10: ";
//read in user input
cin >> secretNumber; //store user input in variable
cout << "\b" << "\b" << "\b" << " "; //<------- this is my attempt to clear the user input
if(secretNumber <= 0 || secretNumber > 10){
cout << "You have attempted to enter a number outside of the acceptable range." << endl;
}
}while ((secretNumber <= 0 || secretNumber > 10)); //repeat do-while loop if user input is out of range
Currently this just prints another line, with a space as the first character, instead of going back to the previous line and replacing the user inputted integer with a " ".
Please do not give me any OS specific solutions, I need this to compile on both windows and linux.
If your terminal emulator (or the command shell you use on Windows) supports basic ANSI control characters, you could output a reverse line feed sequence followed by a kill line sequence. The reverse line feed is necessary because the user will have typed a carriage return in order to terminate the input, so the cursor is no longer on the same line. Those codes are "\033[F" and "\033[K", respectively. But there is no guarantee that this will work.
Historically, you could use the now-withdrawn Posix interface getpass to read a line without echoing. I don't believe that was implemented by Windows, and while it is still part of glibc, its use is discouraged. Unfortunately, there is no standard replacement.
Console-independent terminal control is available in Posix systems using the termios facilities; basically, you just need to turn off the ECHO flag. (See man termios for more details.) On Windows, there is a similar interface. However, it is very easy to get into trouble with these interfaces because you need to re-enable echoing even if the user kills the program with ctl-C (or suspends it with ctl-Z). Getting that right is tricky, and the naive solutions you'll find floating around on the internet typically don't.
Having said that, see Getting a password in C without using getpass (3)? for some possible solutions.
Related
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.
I am trying to figure out if there is a way to move certain characters in line while the user enters a number.
For example, I want the user to input their number between [__]. However, when the user enters the number, it will eventually overwrite the ']'. How would I move the ']' while the user enters numbers?
I am hoping I wouldn't have to loop and get single characters at a time. (I am expecting a double value)
std::cout << "Enter a number between 1 and 10: []\b\b";
std::cin >> variable;
// not sure if I should loop through individual character input from user.
This is only possible if the console supports it, the windows console for example uses different codes to Linux.
The commands you need to send to the terminal are ANSI escape sequences and are described here:
http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html
Position the Cursor:
\033[;H
Or
\033[;f
puts the cursor at line L and column C.
Move the cursor up N lines:
\033[A
Move the cursor down N lines:
\033[B
Move the cursor forward N columns:
\033[C
Move the cursor backward N columns:
\033[D
So for example you could:
std::cout << "Enter a number between 1 and 10: [..]\033[D2";
(You may well need to tweak that string a bit, this isn't something I've used in a LONG time).
To print the prompt and then move the cursor.
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).
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;
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".