This question already has answers here:
Using getline(cin, s) after cin [duplicate]
(13 answers)
Closed 7 years ago.
Consider this code:
#include <iostream>
#include <string>
using namespace std;
int main(){
int n = 1;
string data[13];
while(n > 0){
cin >> n;
for(int i = 0; i < n; i++){
getline(cin,data[i]);
cout << data[i] << endl;
}
}
}
i compiled this in cppdroid on my android. I want to hold n lines in the array. (n <= 13). Everything is fine about that. But when I input an integer in the first line of program, it prints one blank line and on the third line the program takes input for lines. My console window looks like this:
2
This is line 1.
This is line 1.
And this is line 2.
And this is line 2.
I want to remove unwanted spaces.
The
cin >> n;
consumes only the digits you've entered, and leaves a newline (at the least) in the input buffer.
This newline is then read and output by the first executed
getline(cin,data[i]);
cout << data[i] << endl;
To avoid it you can use getline of a string also for the integer input, and e.g. convert to integer via stoi. Or, less robust, you can call the ignore method on the stream to ignore everything up to and including the next newline. It's less robust because formatted input of an integer can put the stream in an error mode where it ignores further input operations until the error mode is cleared.
Re the array, better use a std::vector. Then you don't need to decide on a fixed capacity.
cin >> n reads the number but leaves the newline in the input stream. Your first call to getline reads that, so you start up with an empty line.
The problem is you are mixing calls to getline() with the use of the operator >>.
Remember that operator >> ignored leading white space so will correctly continue across lines boundaries. But stops reading after the input has successfully been retrieved and thus will not swallow trailing '\n' characters. Thus if you use a getline() after a >> you usually get the wrong thing unless you are careful (to first remove the '\n' character that was not read).
The trick is to not use both types of input.
If you're using getline after cin >> yourdata, you need to flush the newline out of the buffer in between.
#include <iostream>
#include <string>
using namespace std;
int main(){
int n = 1;
string data[13];
while(n > 0){
cin >> n;
cin.ignore(10,'\n'); // insert this into your code
for(int i = 0; i < n; i++){
getline(cin,data[i]);
cout << data[i] << endl;
}
}
return 0;
}
Related
I'm trying to input some characters into the array but after hitting enter , the terminal would not accept further input.
#include <bits/stdc++.h>
using namespace std ;
int main() {
char Array[5];
for(int i=0;i<5;++i){
cout << "Enter :";
cin.ignore('\n');
cin >> Array[i];
}
for(auto data : Array){
cout << data << endl;
}
return 0;
}
Any help would be appreciated.
You don't need the cin.ignore() here:
#include <iostream>
int main() {
char Array[5];
for(int i=0;i<5;++i){
std::cout << "Enter: ";
// No use in cin.ignore() here
std::cin >> Array[i];
}
for(auto data : Array){
std::cout << data << std::endl;
}
return 0;
}
Example:
Enter: 3
Enter: 4
Enter: 5
Enter: 6
Enter: 7
3
4
5
6
7
Main thing to note for you is the fact that cin object will skip any leading white space on itself. So, you don't have to worry that cin will read in '\n' on a second iteration, thus, terminating and skipping the input, it won't read it in.
While the ignore('<character>') will extract specified character, know as delimiting character, from the input sequence and discard it. In your case, the character is \n. The cin function stops extracting characters from the stream as soon as an extracted character compares equal to this. So, no way to pass it \n, no way to terminate input normally (you can still pass it EOF).
More on the proper use of the cin.ignore(): When and why do I need to use cin.ignore() in C++.
I also want to include this in the answer: Why should I not #include <bits/stdc++.h>?.
So I was taking input some integers and then taking input some sentences.
This code works fine:
#include<bits/stdc++.h>
using namespace std;
main(){
int c,b,n,i;string s;
cin>>n>>b>>c;
for(i=0;i<n;i++){
cin>>ws;
getline(cin,s,'\n');
cout<<s;
}
}
Example:
3 3 3
This is weird
This is weirdDefinitely makes
Definitely makesNo sense
No sense
However, when I try to omit the cin>>ws inside the forloop, it doesn't work properly, eg this code segment,
#include<bits/stdc++.h>
using namespace std;
main(){
int c,b,n,i;string s;
cin>>n>>b>>c;
for(i=0;i<n;i++){
getline(cin,s,'\n');
cout<<s;
}
}
Example:
3 3 3
This is weird
This is weirdDefinitely makes
Definitely makes
..and terminates there instead of taking all three inputs.
Why is that? cin>>ws extracts all whitespace from the input but isn't getline() doing that too? So why does it not work properly when I omit cin>>ws in the forloop?
std::getline() extract characters until it extracted the first delimiter character (by default '\n'). The delimiter is not stored in the result but it is extracted. It does not extract whitespace in general or multiple delimiter characters.
As an aside: always check whether input works after trying to read a value.
In the example printed, the issue is is that after formatted input, i.e., using the >> operator, whitespaces are not extracted. That is, the first calls to std::getline() extracts the empty string terminated by the initial newline. It generally is necessary to extract trailing whitespace when switching between formatted and unformatted I/O. That is, You'd want code like
if (cin>>n>>b>>c >> std::ws) {
for(i=0;i<n;i++){
if (getline(cin,s,'\n')) {
cout << "i=" << i << ":'" << s << "'\n";
}
}
}
I can't recommend input operations without adding check for success. The output is changed to make it more easily visible what is going on: try the code with/without this particular std::endl to see what is happening.
When you use cin >> it doesn't remove any whitespace after the input. This means the newline that terminated the first 3 inputs is still in the buffer, waiting to be read by the first getline. Since there's nothing before the newline, the first getline delivered an empty string. Your output should have included a newline so you could have seen the empty line, then it would have made sense.
Originally the code you posted showed a cin >> ws just before the for loop which would have eliminated this problem.
The default delimiter for getline() is '\n', so there is no need to include that in the getline call, though, it should not change the functionality.
See for example Same as getline(input, str, input.widen('\n')), that is, the default delimiter is the endline character.
The change in formatting from the integer input to the getline() input leaves some whitespace (endl) after the integer as explained by #DietmarKühl.
You can change the getline() call to eliminate the delimiter to
getline(cin,s);
which will cause getline() to use '\n' as the default delimiter.
I have modified the 'n' variable to count and removed the other integers to make the code a little simpler to read:
#include <iostream>
int main()
{
int i; // index
int count; // number of strings to accept
std::string str;
std::cout << "Input the number of strings you would like me to process: " << std::endl;
std::cin >> count;
if (std::cin >> count >> std::ws) {
for (i = 0; i < count; i++) {
if (getline(std::cin, str)) {
std::cout << "i=" << i << ":'" << str << "'\n";
}
}
}
}
Cin doesn't extract all white spaces, it just gets the first word until the first white space. It is like having a getline with a space delimiter(not quite but close to).
Getline takes the whole line and has the default '\n' delimiter like mentioned above.
Ex:
string a = "Stack Overflow is awesome";
can give you Stack and getline will give you everything at that line
I have problem with the following code:
#include<iostream>
using namespace std;
int main()
{
char a[200];
int i;
for (i = 0; cin.get() != '\n'; i++) {
cin >> a[i];
}
cout << i;
system("pause");
return 0;
}
I don't know why when i input without space 10 char for example. i si equal to 10/2=5 ?
You discard every odd symbol, cin.get() read symbol 1,
cin >> read symbol two, and again cin.get() read symbol 3,
and cin >> read symbol 4 from standard input.
You are throwing out half of your cin results.
When you use cin, a character is read, but you are not assigning it to anything inside the for loop criteria; only inside the loop body are you saving it.
Inside the loop, you read in another character (after the one you already read in during the loop's test criteria) and assign that one. The loop repeats, and the next character read is again thrown away with the line cin.get() != '\n' because you are not assigning the results to anything. And this continues, alternating characters you throw away with characters you "save" into the array.
You get two characters, once increment i variable and only second of them insert in array
int main()
{
char a[200];
int i;
\\ cin.get() - get one char and insert it in a[i]
\\ after that, compare this value with '\n'
\\ if equal, break the loop, if different, continue
for (i = 0; (a[i] = cin.get()) != '\n'; i++);
\\ last character ('\n') should be replaced with '\0'
a[i]='\0';
cout << i;
system("pause");
return 0;
}
while solution:
int main()
{
char a[200];
int i=0;
cin >> a[i];
while (a[i] != '\n')
{
i++;
cin >> a[i];
}
a[i]='\0';
cout << i;
system("pause");
return 0;
}
do - while solution:
int main()
{
char a[200];
int i=0;
do
{
cin >> a[i];
}
while(a[i++]!='\n');
a[i-1]='\0';
cout << i-1;
system("pause");
return 0;
}
As a matter of fact, you are reading the standard input (std::cin) in two different ways, storing its output only once every two character extractions.
std::basic_istream::get (cin.get()) extracts character or characters from stream. Once extracted, whey are forgotten, sent to limbo. You simply ignore them. Which is not what I suspect you want to do.
std::basic_istream::operator>> (cin >> ...) also extracts character or characters (following the type of the right hand side operand).
So, with an input of ten characters, you ignore five of them in your for condition check and store five in the loop block.
A correct way to read the characters would be to use std::getline (en.cppreference.com/w/cpp/string/basic_string/getline):
std::string input;
std::getline(cin, input);
std::cout << input << std::endl;
This example code will simply read a line and output it, verbatim, in the standart output.
I was trying to read from standard input. The first line is the number of lines that I will read. The lines that I read next will be printed again. Here is the code:
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
for (unsigned int i = 0; i < n; ++i)
{
char a[10];
cin.get (a, 10);
cout << "String: " << a << endl;
}
return 0;
}
When I run it and give number of lines, the program exits. I haven't figured out what's going on, so I've decided to ask it here.
Thanks in advance.
Mixing formatted and unformatted input is fraught with problems. In your particular case, this line:
std::cin >> n;
consumes the number you typed, but leaves the '\n' in the input stream.
Subsequently, this line:
cin.get (a, 10);
consumes no data (because the input stream is still pointing at '\n'). The next invocation also consumes no data for the same reasons, and so on.
The question then becomes, "How do I consume the '\n'?" There are a couple of ways:
You can read one character and throw it away:
cin.get();
You could read one whole line, regardless of length:
std::getline(std::cin, some_string_variable);
You could ignore the rest of the current line:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
As a bit of related advice, I'd never use std::istream::get(char*, streamsize). I would always prefer: std::getline(std::istream&, std::string&).
Adding a cin.get() before cin.get(a, 10) will solve your problem because it will read the remaining endline in the input stream.
I think it is important to know this when you are using cin : http://www.cplusplus.com/forum/articles/6046/
I'm trying to collect user's input in a string variable that accepts whitespaces for a specified amount of time.
Since the usual cin >> str doesn't accept whitespaces, so I'd go with std::getline from <string>
Here is my code:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
string local;
getline(cin, local); // This simply does not work. Just skipped without a reason.
//............................
}
//............................
return 0;
}
Any idea?
You can see why this is failing if you output what you stored in local (which is a poor variable name, by the way :P):
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
string local;
getline(cin, local);
std::cout << "> " << local << std::endl;
}
//............................
return 0;
}
You will see it prints a newline after > immediately after inputting your number. It then moves on to inputting the rest.
This is because getline is giving you the empty line left over from inputting your number. (It reads the number, but apparently doesn't remove the \n, so you're left with a blank line.) You need to get rid of any remaining whitespace first:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
cin >> ws; // stream out any whitespace
for(int i = 0; i < n; i++)
{
string local;
getline(cin, local);
std::cout << "> " << local << std::endl;
}
//............................
return 0;
}
This the works as expected.
Off topic, perhaps it was only for the snippet at hand, but code tends to be more readable if you don't have using namespace std;. It defeats the purpose of namespaces. I suspect it was only for posting here, though.
Declare a character to get in the carriage return after you have typed in the number.char ws;int n;cin>>n;ws=cin.get();
This will solve the problem.
Using cin>>ws instead of ws=cin.get(),will make first character of your string to be in variable ws,instead of just clearing '\n'.
It's quite simple.
U jst need to put a cin.get() at the end of the loop.
Are you hitting enter? If not get line will return nothing, as it is waiting for end of line...
My guess is that you're not reading n correctly, so it's converting as zero. Since 0 is not less that 0, the loop never executes.
I'd add a bit of instrumentation:
int n;
cin >> n;
std::cerr << "n was read as: " << n << "\n"; // <- added instrumentation
for // ...
why this happens :
This happens because you have mixed cin and cin.getline.
when you enter a value using cin, cin not only captures the value, it also captures the newline. So when we enter 2, cin actually gets the string “2\n”. It then extracts the 2 to variable, leaving the newline stuck in the input stream. Then, when getline() goes to read the input, it sees “\n” is already in the stream, and figures we must have entered an empty string! Definitely not what was intended.
old solution :
A good rule of thumb is that after reading a value with cin, remove the newline from the stream. This can be done using the following :
std::cin.ignore(32767, '\n'); // ignore up to 32767 characters until a \n is removed
A better solution :
use this whenever you use std::getline() to read strings
std::getline(std::cin >> std::ws, input); // ignore any leading whitespace characters
std::ws is a input manipulator which tell std::getline() to ignore any leading whitespace characters
source : learncpp website
goto section (Use std::getline() to input text)
hope this is helpful
Is n properly initialized from input?
You don't appear to be doing anything with getline. Is this what you want?
getline returns an istream reference. Does the fact that you're dropping it on the ground matter?
On which compiler did you try this? I tried on VC2008 and worked fine. If I compiled the same code on g++ (GCC) 3.4.2. It did not work properly. Below is the versions worked in both compilers. I dont't have the latest g++ compiler in my environment.
int n;
cin >> n;
string local;
getline(cin, local); // don't need this on VC2008. But need it on g++ 3.4.2.
for (int i = 0; i < n; i++)
{
getline(cin, local);
cout << local;
}
The important question is "what are you doing with the string that gives you the idea that the input was skipped?" Or, more accurately, "why do you think the input was skipped?"
If you're stepping through the debugger, did you compile with optimization (which is allowed to reorder instructions)? I don't think this is your problem, but it is a possibility.
I think it's more likely that the string is populated but it's not being handled correctly. For instance, if you want to pass the input to old C functions (eg., atoi()), you will need to extract the C style string (local.c_str()).
You can directly use getline function in string using delimiter as follows:
#include <iostream>
using namespace std;
int main()
{
string str;
getline(cin,str,'#');
getline(cin,str,'#');
}
you can input str as many times as you want but one condition applies here is you need to pass '#'(3rd argument) as delimiter i.e. string will accept input till '#' has been pressed regardless of newline character.
Before getline(cin, local), just add if(i == 0) { cin.ignore(); }. This will remove the last character (\n) from the string, which is causing this problem and its only needed for the first loop. Otherwise, it will remove last character from the string on every iteration. For example,
i = 0 -> string
i = 1 -> strin
i = 2 -> stri
and so on.
just use cin.sync() before the loop.
just add cin.ignore() before getline and it will do the work
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
string local;
cin.ignore();
getline(cin, local);
}
return 0;
}