disallow the line break while reading in a number in c++? - c++

I have a problem.
i want the user to enter a number in my c++ program, but during the input i want to prevent that he just presses enter without having made an input, thus creating a line break.
I have already solved the problem in another place where the user has to enter a character.
I have read the character with getchar, determined the position of the cursor with the ANSI escape sequences and provided the whole thing with a do while loop.
But since I want to read in a number between 0 and 250, getchar would not be suitable.
scanf and cin both wait for a valid input and cause these nasty line breaks.
I have already thought about using getchar anyway and storing the characters in a char array whose indices I then convert to the corresponding numbers which I then add up to the actual number which can then be stored again in an int variable.
But surely there is an easier alternative or?
Translated with www.DeepL.com/Translator (free version)

This line will flush the newline character
cin.ignore(256, '\n');

Related

Two cins in a row, what exactly happens with whitespaces?

cin >> name;
cin >> age;
cout << name << age;
What exactly is happening here if I type a string, then some whitespace and a number? For example Something 20. Does it read Something then sees the whitespace and goes okay that's the end of this first line because a whitespace terminates the reading of the string, goes to the next input and reads 20?
But I also wanna be a bit more specific. Is it okay to say at first when I'm in the console typing Something, that's going into the standard input stream, then getting stored in the buffer and when I press that space it's like pressing enter? And that Something gets extracted and assigned to name? Then that 20 I type is like a whole new unrelated line because I pressed space earlier and so that gets extracted and assigned to age?
How they'll get extracted
The integer gets extracted via std::basic_istream::operator::>>:
Extracts values from an input stream
1-4 ) Extracts an integer value potentially skipping preceding
whitespace. The value is stored to a given reference value.
This function behaves as a FormattedInputFunction. After constructing and
checking the sentry object, which may skip leading whitespace,
extracts an integer value by calling std::num_get::get().
The string gets extracted via std::basic_string::operator>>:
2 ) Behaves as a FormattedInputFunction. After constructing and
checking the sentry object, which may skip leading whitespace, first
clears str with str.erase(), then reads characters from is and appends
them to str as if by str.append(1, c), until one of the following
conditions becomes true:
N characters are read, where N is is.width() if is.width() > 0,
otherwise N is str.max_size()
the end-of-file condition occurs in the stream is
std::isspace(c,is.getloc()) is true for the next character c
in is (this whitespace character remains in the input stream).
And in FormattedInputFunction:
if ios_base::skipws flag is set on this input stream, extracts and
discards characters from the input stream until one of the following
becomes true:
the next available character on the input stream is not
a whitespace character, as tested by the std::ctype facet of the
locale currently imbued in this input stream. The non-whitespace
character is not extracted.
the end of the stream is reached, in which
case failbit and eofbit are set and if the stream is on for exceptions
on one of these bits, ios_base::failure is thrown.
And as stated in Basic Input/Output from cplusplus.com:
...Note that the characters introduced using the keyboard are only transmitted to the
program when the ENTER (or RETURN) key is pressed.
...
...cin extraction always considers spaces (whitespaces, tabs,
new-line...) as terminating the value being extracted, and thus
extracting a string means to always extract a single word, not a
phrase or an entire sentence.
Testing
Compiling and testing your program with leading and trailing whitespaces via MSVC-v142 compiler:
AA 123 some trailing whitespaces
Prints out:
AA123
Read also
Stackoverflow: Clarify the difference between input/output stream and input/output buffer
Learn cpp: Input and output streams

istringstream ignores first letter

I am trying to access different words in a string using std::istringstream and I am also doing so with multiple test cases.
int t;
cin>>t;
while(t--)
{
string arr;
cin.ignore();
getline(cin,arr);
istringstream iss(arr);
string word;
while(iss>>word)
{
cout<<word;
}
}
For the first test case, everything is perfect (i.e. it outputs the correct words). But for every subsequent test case, the first letter of the first word is left out.
Example:
Input:
4
hey there hey
hi hi hi
my name is xyz
girl eats banana
And I'm getting:
Output:
hey there hey
i hi hi
y name is xyz
irl eats banana
Can anyone please suggest me what to do and why is this error occurring?
Your problem is that formatted input, i.e., something like in >> value conventionally skips leading whitespace before attempting to read. Unformatted input, on the other hand, doesn't skip leading whitespace. With the std::cin.ignore(); in your loop you make the assumption that std::getline(std::cin, arr) would leave the newline in the input like the input of t does. That is not so. std::getline() extracts and stores all characters up to the first newline where it stop, still extracting the newline. So, you'd remove the cin.ignore(); from the loop.
The key question becomes how to switch between formatted input and unformatted input. Since the newline upon entry of a numeric value may be preceded with arbitrary spaces which you probably also want to ignore, there are essentially to ways:
std::cin >> std::ws; skips all leading whitespace. That may include multiple newlines and spaces at the beginning of the line. Skipping those may not necessarily desirable.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); ignores all characters up to and including the first newline. That would allow for empty lines to follow up as well as lines starting with leading whitespace.
This line is the culprit: cin.ignore();.
When std::basic_istream::ignore is called without any arguments, it ignores exactly 1 character.
In your case, std::cin.ignore() will ignore the first letter, but not for the first test case, because at that point std::cin is empty, so there is nothing to ignore. But then, std::cin has the other words in it, so it ignores 1 character from the first word.
According to the documentation of std::basic_istream::ignore:
Extracts and discards characters from the input stream until and
including delim. ignore behaves as an UnformattedInputFunction
Its worth to mention that std::basic_istream::ignore will block and wait for user input if there is nothing to ignore in the stream.
With this in mind, lets break down what your code does:
the first time you call this function in your loop, it is going to
ignore the new line character that is still in the buffer from the
previous cin>>t operation. Then the getline statment will wait and read a line from the user.
The next time around, since there is nothing in the buffer to
ignore(as std::getline doesn't leave the new line character in the
buffer), it is going to block and wait for input to ignore. So
the next time the program block and waits for input, it is because
of the ignore() function,not the getline function as you would
have hoped, and the moment you provide an input(i.e you second test
case),one character from the input is going to be ignored.
The next getline function will not block since there is something
in the buffer left by the previous ignore function after it
ignores the first character of the input so getline will read the
remaining string which will happen to be one character short.
The process continues from step 2 until your loop terminates.
int t;
cin>>t;//this leaves new line character in the buffer
while(t--)
{
string arr;
cin.ignore();//this will ignore one character from the buffer,so the first time
//it will ignore the new line character from the previous cin input
//but next time it will block and wait for input to ignore
getline(cin,arr);//this will not block if there is something in the buffer
//to read
...
}
The solution would be to move the ignore statement out of the loop and next to your cin>>t statement. It's also better write ignore(INT_MAX,'\n'); in this case. You might also want to read this answer to see when and how to use ignore.

Reading whole line with std::cin

I would like to figure out how to read a whole line (including spaces) with std::cin. I am aware of the existence of std::getline, I would just like to figure out how to do it with std::cin so I can better understand iostream in C++. I've tried using a for loop with std::cin, however it keeps reading past the end of the line. Any help would be greatly appreciated.
Also the cin << only allows us to enter one word into a string.
However, there is a cin function that reads text containing blanks.
std::cin.get(name, MAX);
get will read all characters including spaces until Max characters have been read or the end of line character (‘\n’) is reached and will put them into the name variable.
You should decide what is MAX.

Prompting User For Instructions

I am trying to write an infix calculator and I want to start the program off asking the user if he/she needs help or not. I have written the code that will offer instructions if the user inputs 'y' or 'n', however, in both cases, the program ends without allowing the user to enter an infix expression and running the rest of the program. It seems as though the program is breaking in main right after cout << "Expression?"; It does not give the option for the user to input anything after that.
When you use cin >> help, you're only reading one character, the y or n. The newline after that is left in the input buffer.
Then when the main function uses getline, it reads up to the next newline, which is the one that was left in the buffer by provideHelpIfNecessary. So it just reads a zero-length line, and that causes the while loop to break.
Use getline in provideHelpIfNecessary instad of reading just one character.

Will cin recognize \n typed in from keyboard as a newline character?

I am a beginner for C++ so I'm sorry if this question sounds stupid..
I made this little program to help me get familiar with the properties of cin:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string next;
cout<<"Enter your input.\n";
cin>>next;
cout<<next;
return 0;
}
When I typed in \n from the keyboard input, I was returned \n.
Also, when I changed the variable next from a string to a character and gave it the same input as above, I was returned only a \.
My question is: Why am I not returned with a new line instead? Doesn't cin recognize \n type in from keyboard as a newline character? Or is it just applicable to cout?
\n is an escape sequence in C++; when it appears in a character constant or a string literal, the two character sequence is replaced by the single character representing a new line in the default basic encoding (almost always 0x0A in modern systems). C++ defines a number of such escape sequences, all starting with a \.
Input is mapped differently, and in many cases, depending on the device. When reading from the keyboard, most systems will buffer a full line, and only return characters from it when the Enter key has been pressed; what he Enter key sends to a C++ program may vary, and whether the file has been opened in text mode or binary mode can make a difference as well—in text mode, the C++ library should negotiate with the OS to ensure that the enter key always results in the single character represented by \n. (std::cin is always opened in text mode.) Whether the keyboard driver does something special with \ or not depends on the driver, but most don't. C++ never does anything special with \ when inputting from a keyboard (and \n has no special meaning in C++ source code outside of string literals and character constants).
If you need your program to recognize \n as a new line character at input you can check this out:
https://stackoverflow.com/a/2508814/815812
What Michael say is perfectly correct.
You can try out in similar way.
Technically speaking, this depends on things outside your program, but assuming your terminal simply passes the individual bytes corresponding to the '\' and 'n' characters (which I think any sane one will), then the behavior you're seeing is expected.
"\n" is nothing more than a shortcut added to the programming language and environment to let you more easily represent the notion of the ASCII return key. It's not a character itself, just a command to tell the program to generate a non-printable character that corresponds to pressing the Enter key.
Let's say you're in Notepad or whatever and you press the Tab key. It tabs over a spot. Typing "\t" just enters the literal characters "\" and "t". Internally, whoever wrote Notepad had to say what it should do when the user pressed Tab, and he did so by using the mnemonic like
if(key == '\t') {
// tab over
}