Working with strings in C++ - c++

I'm working with strings in C++. I recently came across a problem when entering strings. I'm using cin >> string; to get my string as user input. When the user enters a space into the string, the next input is automatically filled out with the remaining letters, or sometimes left blank. As the next input string is often an integer, this will result in an unpleasant bug. What's a good fix for this?
EDIT: Here's the current code:
cout << "Please print the enemy's name: ";
getline(cin, enemyName);

You probably want to get all input into the string up until the user presses enter. In that case, it can be said that what you really want is to read a "line" of text. To do that, you'd use std::getline, like so:
std::getline(cin, enemyName);
That is assuming enemyName is defined as an std::string. If enemy name is a c-style charater array, you'd want to use cin.getline, like this:
cin.getline(enemyName, sizeof(enemyName));
But, try to avoid using C-style character arrays at all in C++.

The behavior of >> with strings is intentional; it interprets whitespace characters as delimiters to stop at, so it's really best at chomping words. std::getline() (#include <string>) uses '\n' as the delimiter by default, but there's also a version of std::getline() that takes a custom delimiter character if you need it.

Use getline(cin, string); instead.

Use getline() to read in an entire line at a time.
getline (cin, string);

Related

C++ Beginner: std::cin to std::string

Just started learning C++ and encountered an issue with strings while doing an exercise.
So I initialized std::string phrase; while allowing the user to input and save the phrase to the string with std::cin >> phrase;. Now my issue comes when the inputed phrase has spaces, I noticed that the computer will only save the characters up till the first word only.
With the phrase "sunsets are great", the phrase.size() only came out to 7, so the following words after the first space were not saved.
The entire exercise is supposed to compare all of the letters in the whole inputted string with another set of values. Should I be using a different function for this?
Any help would be appreciated! :)
I have also had this problem when i was first starting out.
whenever you want to read a string i would use the getline.
ie
string phase
cout << "enter phase" <<endl;
getline(cin,phase);
If you want to take an entire line including space(s), you may use the following code:
string str; // declaration
getline(cin, str);
Remember: cin.get and cin will trim all the inputted characters just after first space.
Enjoy.

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.

Taking string input

How to take string input in C++?
I generally use gets. But is doesn't work for 2-D arrays.
On the other hand cin ignores the text after a blank.
I want the input to be the exact unformatted text.
You can use it like this:-
char input[100];
cin.getline(input,100);
Check out the cin.getline()

Good way to tokenize a string to store values? Or alternative for user input

Hello again Stackoverflow, I'm here again asking a question for my C++ programming class. The problem I am facing is mostly to due with user input from the keyboard. I need to be able to take the user input to decide what function to call and what arguments to give the function. For example something like add 5 would call the add function with the argument 5. At first I tried overloading the >> operator to take both a string and an int but the problem I ran into was the program was unable to take input without the int such as deletemax so I had to throw that idea out. So now I am back to tokenizing the input but we are not allowed to use Boost for this program so I came up with something like this using sstream
bool out = false;
string token;
string In;
int num;
do
{
cout << "heap> ";
cin >> In;
istringstream iss(In);
while(getline(iss, token, ' '))
{
cout << token << endl; //I know this is incorrect but just not what to replace it with
}
out = ProcessCommand (token, num); //Takes string and int to call correct functions
} while (out != true);
The problem lies in that I'm not quite sure how to correctly tokenize the string so I can get 2 string and convert the second string to an int. Can anyone offer me some assistance? I would greatly appreciate it. Also if there is a better way to go about this than I am trying I would also like to hear it.
Thanks for any help you can give me.
Googling "C++ string tokenize" will get you plenty of hits, with the first hit being on Stackoverflow. But you should take a stab at it. I'm guessing it's the point of the exercise.
You said "argumentS", which suggests that commands you support take varying numbers of arguments. I'd break it down like this:
read a line from the user
split line into 'tokens' on space boundaries, store tokens in a list
based on the first token in the list, choose a command to execute
pass the list of tokens to the command, so it can validate/interpret them as arguments
The tricky part is #2. Do you know about container classes yet? You can use vector<string> to store the chunks you parse. To do the actual parsing, you iterate through the characters of the string. Skip whitespace until you find a non-whitespace character (or run out of characters). Save this position: start. Then skip non-whitespace until you find whitespace (or run out of characters). Save this position: end. Copy the substring represented between from start to end and copy that to your token list.
Working out the actual details of this, making sure you don't have off-by-on-errors, etc. is going to be challenging if you've never done it before, which I'm guessing is the point.
You don't need to read in the whole of user input all at once.
For example you could read in the first bit of user input (the operation, add or deletemax, etc). From there depending on the operation you could continue to read arguments from input (in the case of add) or begin performing the operation immediately (in the case of deletemax).
One way would be to have a std::map of function names as keys and required number of arguments as values. You'd read a line of input, get the function name and then decide whether you need aditional arguments. I'd write a function that'd return a vector of arguments extracted from a string stream or an empty vector in case the input was invalid.

Cin until end of input

I need to read in a string and then an integer until the user indicates end of input (ctrl-d in linux). Again, I am stuck. Currently I have a while loop:
while (getline(cin, line))
However, that gives an entire line and then I cannot seem to separate the string from the integer. Suggestions would be most appreciated! :)
If the string and the integer is separated by whitespace;
Do this:
while(std::cin>>your_string>>your_num>>std::ws){}
You can choose your own delimiter, by writing a manipulator yourself.
Another approach would be to do it your way, and put the input line into a stringstream and extract the string and numbers from it. That approach seems roundabout to me as you get strings from a stream only to put it into another stream.
cin>>a
The above statement reads a token from standard input and stores it in the a variable. What is less known is that it also returns a bool value. When you reach the end of all standard input, the above statement would return false.
Use it in an if statement!
if(c>>a){
cout<<"End of standard input has been reached!";
}