Difference between entering values in cin using spacebar and enter key? - c++

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)

Related

in c++ program after pressing enter , "cin" will feed all Variables

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.

When the input will stop?

Hi guys i have the following question:
string s;
std::cout << "give me a string" << std::endl;
while (std::cin >> s){
std::cout << "give me a string" << std::endl;
}
cin.clear();
if s was an integer then i know that if i typed a char then the while would break. If it was an integer and typed a double the same would happened. But what about strings ?? Somewhere I read that in windows (as I am writting at netbeans in windows) you have to press ctrl+z and then it stops as it is taken as a false string. But when i do this , the process freezes and nothing happens.
You need to send the EOF signal, which in Netbeans is Ctrl + D.
However, hitting Enter twice will result in the condition of your loop to resolve in false, causing the loop to stop. That's excpected: How is "std::cin>>value" evaluated in a while loop?
If that doesn't work, use Ctrl + z and a newline character, which is the EOF signal in Windows, as stated here. Ctrl + D is for Linux though, but it works in your case.
The EOF signal closes the input stream, thus breaking the loop.
Moreover, in Netbeans (if the above doesn't work) it seems that you need to run your application from the command prompt to achieve this. Another attempt would be to "press Ctrl + z after pressing Enter", as stated here.
The loop will stop when the input stream is closed.
If you run the program from a shell, then the input stream may be open indefinitely. Exactly how you would close the stream in a terminal, depends on what terminal you are using.
In UNIX, the stream is closed when you send empty input. ctrl + d is the standard key combination for sending (flushing) the input to the stream (^d is the ASCII control code EOT, end of transmission). Pressing enter also sends the input, but it also inserts the end of line character, so it is not possible to use it to send empty input.
ctrl + z is similar in windows, but it has different behaviour (wikipedia):
The EOT character in Unix is different from the Control-Z in DOS. The DOS Control-Z byte is actually sent and/or placed in files to indicate where the text ends. In contrast the Control-D causes the Unix terminal driver to signal the EOF condition, which is not a character, while the byte has no special meaning if actually read or written from a file or terminal.

Dynamically Change Console with User Input

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.

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).

Run Time Error: Program skipping prompt for second and third names [duplicate]

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);