Prompting User For Instructions - c++

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.

Related

How can i handle invalid input to cin(cpp)

when i use the code below,
char command;
cin >> command;
i want to get only ('a','c','d') as inputs.
In other alphabet(int) cases, i can solve the problem using 'switch statement'
But when someone types multiple characters, my program doesn't know what is the problem.
Just, take one charcter of multiple characters.
In conclusion, I want to detect the multiple character input case.
And this happens, i want to print error, then program to keep running.

disallow the line break while reading in a number in 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');

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.

C/C++ , How to deny inputting char/string when waiting for the user to input a int , float or whatsoever?

A beginner question !
How to oblige the user to only input a number (int,float,long..) so he cannot input a char or a string when you're waiting for a number :D thanks
In general input validation can be done in two distinct ways:
Validate input after the user entered his input, and display an appropriate message, along asking the user to re-enter valid input.
Keep a state machine (FSM) that knows which input format is expected at a particular point . When the user is going to input particular characters, these are checked to fit for the current state's rules.
The 1st solution is easy to do, because you can check input operations for particular fields:
std::istream& is = <reference to any valid input stream>;
double value;
if(!(is >> value)) {
// Issue error message
}
The 2nd solution needs to peek for characters as they are typed in, and are immediately checked to become part of the input (and be echoed at the tty), or not. That's not possible in a simple, OS independent way.
Though there are techniques available, that enable you to restrict character inputs from std::cin according your current parser FSM state. Check this post for more information about how this can be achieved.
There aren't any standard C/C++ libraries to prevent the user from entering a string where a number is expected.
If you are using scanf or fscanf, you can check the value returned from the function to make sure that you were able to read the expected number of data.
If you are using std::cin or std::ifstream, you use fail() to check whether the operation succeeded or not.

Data validation from getline in C++

I want to ask the user if they want to continue playing another round or quit. If they want to continue I expect them to enter two words in getline, but if they enter quit, I want to break;. Is this possible?
Can I check to see if the first letter is a "q" and then use putback if it is not? Or can I check the whole word and putback if it is not quit (I would not know the length of the word). Id there some other way I can approach this?
Thank you!
Yes.
I recommend using getline to read each line of user input. Then parse the string in order to determine what action to take. I don't see how a putback would be useful if it were possible. If necessary you can use a stringstream to get numeric info out of the string, or you can simply compare characters. It is up to you to determine the approach but there are a variety of ways in which you could design the program.
Take a look at this. Try to avoid the common gotchas associated with standard streams otherwise you will soon be googling for answers to other questions.
http://www.parashift.com/c++-faq/input-output.html