Taking input as array of words in c++ - c++

std::vector<std::string> words;
std::string word;
while (std::cin >> word)
words.push_back(word);
cout<<words[1];
i am using this to take input to create an array of words with whitespaces.but after ending of sentence using Enter, i am not getting any output.

i am using this to take input to create an array of words with whitespaces.but after ending of sentence using Enter, i am not getting any output.
That's because
while (std::cin >> word)
words.push_back(word);
does not stop when you press Enter
It stops when there is no more data in std::cin. You have to enter EOF to get out of the while loop.
Useful link: How do i enter an EOF character in this program?.

using
getline(cin,word)
instead of
cin<<word
will allow you to input words with whitespaces.
Even, vector starts at index 0, hence output
words[0]
instead of
words[1]
will output the entered value. that is the problem.

Related

How does two consecutive "cin" commands work?

I read that cin terminates as soon as it sees a newline character or white space and it doesn't consume that and leaves it in the input buffer.
Therefore, between cin and cin.getline() commands, we should add a cin.get() to consume the endline character.
But if this is the case, how does two cin commands work?
For eg:
int N;
int M;
cin>>N;
cin>>M;
Once we take the input of N and press enter, then a newline character must be left in the input stream. When we reach to line cin>>M, how does it work given that cin should terminate as the character in the input stream now is "\n".
Please help me resolve my confusion. I'd be glad to know how the input and output in C++ works.
If you enter 1 5 at the prompt for N, N will be assigned 1 and M will be assigned 5. The spacees in between just get ignored by both. If you enter 15 then N will be assigned 15 and there will be a blinking cursor waiting for input for M

Getting multiline sentence input in c++

I am trying to take multiple lines of string input (may contain spaces) in c++ using 2D char array but the loop gets terminated without taking any input for n=1 in the code:
When n=2, it takes only one input and when I try to print input[0], it prints blank. But for cout<
char input[100][100];
int n,i;
cout<<"Enter no of lines : ";
cin>>n;
cout<<"Enter "<<n<<" sentences : "<<endl;
for(i=0;i<n;i++)
cin.getline(input[i],100);
This is a common problem when mixing formatted and unformatted input. After a formatted input, the internal buffer is positioned before the first blank character and before the \n. The bullet proof way would be to always use getline and then scan the first line to extract the number of lines. But for such a simple case, it is enough to use a dummy getline after reading the number of line to skip the end of line:
char input[100][100];
int n,i;
cout<<"Enter no of lines : ";
cin>>n;
cin.getline(input[0], 100); // skip the end of line
cout<<"Enter "<<n<<" sentences : "<<endl;
for(i=0;i<n;i++)
cin.getline(input[i],100);
But:
you should always test cin after a read (what if the user types erroneously e instead of 4?)
you should avoid char arrays and always use string in C++ (simpler, cleaner, less error prone)
When you enter number of lines(say 4) you press 4 and then enter key. It is stored as 4\n in stdin that is standard input. When you read using cin.getline() you are reading \n. You will have to use cin.ignore to ignore existing buffer in stdin. However using >> operator is better since it handles newlines.
For multiline input you can input a third parameter to getline(): a delimiter specifying what indicates the end of your input.

How does cin works in a while loop when the inputs are given in a single line with white spaces?

Consider this small piece of code:
#include <iostream>
#include<stdio.h>
using namespace std;
int main() {
int a;
while(true){
cin>>a;
cout<<a;
}
return 0;
}
Input
1 2 3 5 7 23
Output
125723
How I thought it will run is:
First iteration
1. Reads the first input ie '1' and stops reading further, right after reading the whitespace.
2.Prints the value 1.
Second iteration
1. Again asks for new input
2. Print that in the second line
But that doesn't happen instead it reads the elements we gave after space
First iteration:
Peek at next character in the stream. It's a digit ('1'), so read it.
Peek at next character in the stream. It's not a digit (' '), so don't read it; store 1 in a and return from >>.
(Output 1.)
Second iteration:
Peek at next character in the stream. It's whitespace (' '), so read and ignore it.
Peek at next character in the stream. It's a digit ('2'), so read it.
Peek at next character in the stream. It's not a digit (' '), so don't read it; store 2 in a and return from >>.
(Output 2.)
And so on ...
The point is that >> does not care about lines. cin is one long input stream of characters (some of which may be '\n'). The only thing you can do is read more characters (and then maybe decide that you don't want to do anything with them).
cin is not necessarily connected to a keyboard. The program that started you gets to decide where cin reads from. It can be a file, a network socket, or interactive user input. In the latter case, reading from cin may block until the user types more input, but it will never cause input to just be dropped.
If you want a sane user interface, always read whole lines and process them afterwards:
std::string line;
while (std::getline(std::cin, line)) {
// do stuff with line
}

Switching from formatted to unformatted input in C++

I have an input text file. The first line has two int numbers a and b, and the second line is a string. I want to use formatted input to do file >> a >> b, and then unformatted input to get the characters of the string one by one. In between the two steps, I need to skip over the '\n' character at the end of the first line. I used
while(file.get()<=' ' && !file.eof()); // skip all unprintable chars
if(!file.eof()) file.unget(); // keep the eof sign once triggered
to make the input format more flexible. The user can now separate the numbers a and b from the string using an arbitrary number of empty lines '\n', tab keys '\t', and/or space keys ' ' -- the same freedom he has to separate the numbers a and b. There's even no problem reading in Linux a text file copied from Windows when every end of line now becomes "\r\n".
Is there an ifstream function that does the same thing (skip all chars <=' ' until the next printable char or EOF is reached)? The ignore function does not seem to do that.
Yes, there is: std::ws manipulator. It skips whitespace characters until a non-whitespace is found or end of stream is reached.. It is similar to use of whitespace character in scanf format string.
In fact, it is used by formatted input before actually starting to parse characters.
You can use it like that:
int x;
std::string str;
std::cin >> x >> std::ws;
std::getline(std::cin, str);
//...
//std::vector<int> vec;
for(auto& e: vec) {
std::cin >> e;
}
std::getline(std::cin >> std::ws, str);

Asking the user to input a char and then a string

I'm writing a simple program that asks a user to input a letter. And then I want him to input a phrase. When it's just a single string I don't have a problem.
char c;
string s;
cin >> c;
cin >> s;
But when I want a phrase
cin >> c;
getline(cin, s);
When I run the program after the user inputs a letter and hits enter I don't get a chance to input the phrase. Of course if I type the character and enter a phrase after a space the program works fine.
On the contrary when I input a character and then enter a single string after a space using the first method, it won't record the string.
Why does it do this?
When ever you write a character and press enter, actually 2 char are send to the buffer: the character itself and \n as the result of the enter key press. Your cin >> c; reads the first character only while \n still remains in the buffer. Since std::getline() reads everything before it encounters a \n character and since \n is the first character it encounters it doesn't read anything and the program terminates. Add a std::cin.ignore(); (to ignore the \n) before std::getline and the code will work.
Since c only takes a character, the enter key that the user presses is given to s so anything other than that is not recorded. Only press a single key and no enter for the character. Or else just use a string anyway.