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.
Related
I have a program that takes two numbers and shows them on the screen.
However, when I hit "enter" after I input the first number, my program shows the answers before letting me input the second number.
Why does this happen?
int main()
{
int n1;
float n2;
cin>>n1;
cin>>n2;
cout<<"int n:"<<n1<<endl<<"float n:"<<n2;
return 0;
}
I wanna input 0.25 and 35 but when I write 0.25 and hit enter suddenly shows the answer "int: n:0 float n:0.25" it doesn't let me write second num. my os is Win10 and this program compiled with DevCpp
It works when both variables are ints.
There is no difference between cin>>n1; cin>>n2; and cin >> n1 >>n2. Enter key only serves as signal to sychronize input buffer and stream buffer. cin doesn't input per line, it parses buffer when there is available volume of data. If parse incomplete, it waits. If parse can't be done, it stops and state bit changes. To continue parsing you have either ignore or clear part or whole buffer content.
Something wrong was entered in first line, causing cin to go into bad() state. Edge case might happen if you're running program through a remote terminal, some incorrect character could slip in, e.g. ^M generated by new line from Windows would break cin stream on Linux. That's also case if you input from a file which was saved on different platform. On Windows line ends consist of two characters, #10 and #13. On linux steams expect only #13 as a new line and buffer flush signal, #10 is an unexpected character.
Edit (after OP gave information about input data):
"0.25" would be parsed as "0" and ".25", that expected and documented stream behavior. Parsing for n1 had stopped as soon as stream encountered character which doesn't fit int pattern, which could be space, end of line, alphabetic or punctuation. Period considered a punctuation in this case
Then it tries to get a float from stream input and buffer contains ".25". It's a legal float notation and it gets assigned to n2.
When you have both "int", you cannot get second value at all with same input, it always will be 0, because cin locks up in bad state, i.e. method its istream::good() returns false. You have to check state of stream after reading variables. Any further formatted reading that wouldn't be able to parse .25 wouldn't advance stream past that point.
If you want to read from stream exclusively line by line, you have to use istream::getline() method to get the string. There is also method get which can acquire content of stream and ignore which allows to discard part of stream.
What is the difference between inputting a sequence of values for an array of integers in cin using a SPACE and an ENTER key?
For example -
If I have to input a sequence of numbers in an array and stop receiving the input as soon as 0 is entered by the user in the chain of values. It works correctly if ENTER is pressed on the keyboard to separate each number during input whereas on using SPACE it doesn't stop the input process. Can the below code be modified in some way, so that it works for the SPACE as well?
#include<iostream>
using namespace std;
int main()
{
int arr[10];
int i=-1;
do{
cin>>arr[++i];
}while(arr[i]!=0);
i=-1;
do{
cout<<"\n"<<arr[++i];
}while(arr[i]!=0);
}
"It works correctly if the enter key is pressed to separate each number during input whereas on using the space bar it doesn't stop the input process."
ENTER triggers to read the input stream from an input terminal with cin, while SPACE doesn't.
Usually ENTER from a terminal expands to have the input from the prompt plus a '\n' or '\r' '\n' character sequence sent, and it's considered part of the input.
"Can the below code be modified in some way, so that it works for the space bar as well?"
No, not unless you manage to have a terminal sending input to your program using the SPACE key.
In the end it doesn't really matter for the parsing if you input
1 2 3 4 >ENTER
or
1 2 >ENTER
3 4 >ENTER
std::istream will handle receiving ' ', '\t' or '\n' characters (see std::isspace()) transparently. To send these characters to input is still triggered by the terminal when the ENTER key is pressed.
Space and enter are doing the same thing with respect to cin. It's your mechanism of entry (e.g. your terminal program) that is treating space and enter differently: terminals usually don't pass anything along to your program until you hit enter.
To do what you want, you need to use a library that lets you interact with your terminal. (or maybe your terminal has options you can configure to do this)
Referring to two questions:
Incorrect output from C++ Primer 1.4.4
Confused by control flow execution in C++ Primer example
My question is answered in both of those posts, but I want to delve further.
First, I know this is only the beginning, but let's say I make a fully functional program that runs in a designed window. By that level, will I already know how to implement a EOF? I can't expect someone running my program to know that they need to hit Control-Z.
Is there a way to implement a specific code that functions so that it does not need me to type in an unrecognized value?
Also one guy in those questions somewhat answered the importance of EOF, but how come the program doesn't even post the final cnt - 1?
Let's say I do the numbers 10 10 10 20 20 20. Without EOF, this will only show the "10 repeats 3 times." How come the program doesn't at least type in the count "10 repeats 3 times and 20 repeats 2 times" minus the final one with white space?
lets say I make a fully functional program that runs in a designed window. By that level, will I already know how to implement a eof? I can't expect someone running my program to know that they need to hit ctrl + z.
You could either tell the user explicitly to do a specific action to end input or the design of the window itself could tell the user the information implicitly. For instance, a dialog box could ask the user to enter input and click an OK button when done.
Is there a way to implement a specific code that functions so that it does not need me to type in an unrecognized value?
It seems like you would rather use a newline character to terminate your input. An example of this usage could be std::getline. Instead of writing
while (std::cin >> val)
you could instead use
std::string line;
if (std::getline(std::cin,line))
and assume that your user's input only consists of one line of values. There are plenty of other ways to similarly achieve this task depending on how you want to constrain the user's input.
Let's say I do the numbers 10 10 10 20 20 20. WIthout eof this will only show the "10 repeats 3 times." How come the program doesn't at least type in the count "10 repeats 3 times and 20 repeats 2 times" minus the final one with white space?
Without the eof your program is still executing the while (std::cin >> val) loop since std::cin >> val has not yet received invalid input.
Since the line
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
occurs after that while loop finishes execution, you don't (yet) see any information about the three 20's in the input.
When you are reading a sequence of inputs you'll need some indication when your down. That could be a sentinel value ("enter 999 to stop reading"; you'd need to detect that while reading), an invalid input ("enter X to stop reading"; when reading an int the value X is illegal and causes the stream to got into failure mode, i.e., have std::ios_base::failbit set), or the more conventional "there isn't anything more to read". For a file, the last conditions is straight forward. When reading data from the console you'll either need to teach people how to terminate the input or you'll need to use a different approach.
If you want to intercept any keypressed and react on them directly you may do so, too. You could, e.g., use ncurses and control your input via that. You could also set the concole to non-buffering (on POSIX systems using tcgetattr() and tcsetattr() to clear the ICANON flag) and deal directly with all key presses to decide whether you want to continue reading or not.
Although I'm certainly up to doing fancy I/O stuff I normally don't bother: users will understand the "end of input" character and just deal with it. That is, my input normally looks something like this:
while (in >> whatever_needs_to_be_read) { ... }
... or, if the input is genuinely line oriented
for (std::string line; std::getline(in, line); ) { ... }
The function doing this input will then be called with a suitable std::istream which may be std::cin although I have typically some way to also read from a file (in addition to the shell-privided input redirection).
BTW, despite some indications in the questions referenced, "EOF" is not a character being read. It is a character entered, though (normally). ... and it is quite conventional to "know" the end of input character (on POSIX systems a ctrl-D and on Windows a ctrl-Z). You can use other indicators, e.g., the "interrupt" (ctrl-C) but that takes more work and doesn't integrate nicely with stream. To use the interrupt chacter you'd need to setup a signal handler for SIGINT and deal with that. One slightly annoying part of doing so is that if you get it wrong you'll need to find a different way to kill the program (e.g. on POSIX using ctrl-Z to put the process to sleep and kill it via a harsher signal).
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Program is skipping over Getline() without taking user input
Alright, so I have a program that is running and at the start it prompts you for the data fill the data members. The program does this for 3 different objects.
My problem is that, at run time, after inputting data for the fist object the program proceeds to skip input for the second name and goes straight to the next option. It does the same thing for the third option's name. It also does this when you get the chance to change the data.
"Enter CD Name: Microsoft Word
1-Game
2-Word
3-Compiler
4-Spreadsheet
5-Dbase
6-Presentation
Enter the number that corresponds with the CD's Type: 2
Input CD Cost: 15.23
Enter CD Name: 1-Game <- ((Skips the input part and takes you directly to the menu!))
2-Word
3-Compiler
4-Spreadsheet
5-Dbase
6-Presentation
Enter the number that corresponds with the CD's Type:"
The issue is most likely in my member function, but I'm not sure what the issue is.
Here's my member function code:
void CDX::LoadInfo() //Prompts, validates and sets data members
{
cout << "Enter CD Name: ";
getline(cin, Name);
int choice=0;
do
{ cout << "1-Game\n2-Word\n3-Compiler\n4-Spreadsheet\n5-Dbase\n6-Presentation" << endl;
cout << "Enter the number that corresponds with the CD's Type: ";
cin >> choice;
} while ((choice <1)||(choice>6));
switch(choice)
//Code for case-switch statement goes here)
So what am I missing? Is this a buffer issue or am I prematurely ending the code in some way that causes it to skip?
The conversion of a number stops when it finds a character that can't be converted.
In that case, the character is '\n'
When you use getline to read a line, this character is read and discarded, but when you read a number, it is read (to know if the number continues or not) and if it is not part of the number, it is left in buffer for the next read.
Example:
If you write:
"29312"
and press enter, your buffer will be filled with
"29312\n".
If you use cin >> number, to read stdin, it will consume the digits, but will left in the buffer the "\n".
In the next time you call getline, it will read an empty line that was left in the buffer.
I think it's because the first 'getline(cin, Name)' gobbles up the last newline keypress. When you enter the cost and press ENTER, the call to getline is completed.
You can keep an extra getline after taking the cost so that it consumes the newline. Then, I think, it will run correctly.
You have read the "CD Cost", but the newline remains in the input buffer. Skip whitespace before reading the CD name:
ws(cin);