When i write this code i could not enter two lines as input where each line contains 3 to 5 words by gets() function:
int main()
{
int t;
cin>>t;
char nm1[50],nm2[50];
while(t--)
{
gets(nm1);
gets(nm2);
puts(nm1);
puts(nm2);
}
}
But when i add a gets() function earlier before while() function now i can enter two line of strings like this :
int t;
cin>>t;
char nm1[50],nm2[50];
gets(nm1); //using gets() function here//
while(t--)
{
gets(nm1);
gets(nm2);
puts(nm1);
puts(nm2);
}
So, what is the logic behind this?
Don't use gets. See Why gets() is deprecated?.
Don't mix cin and functions from stdio.h. By default, cin is synchronized with stdin. However, it is possible to make them stay out of sync by using
std::ios_base::sync_with_stdio(false);
See http://en.cppreference.com/w/cpp/io/ios_base/sync_with_stdio for further details.
Real problem.
cin >> t;
leaves a newline character in the input stream. The next call to gets reads that. If you don't want gets to read that, you have to add code to read and discard the rest of the line.
Here's what I suggest:
int main()
{
int t;
cin >> t;
// Ignore the rest of the line.
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
char nm1[50],nm2[50];
while(t--)
{
cin.get(nm1, 50);
cin.get(nm2, 50);
puts(nm1);
puts(nm2);
}
}
Make sure to dd
#include <limits>
to be able to use std::numeric_limits.
in the cin>>t you entered a number and then pressed enter \n, and the end of line is still waiting in the buffer, if you read another integer cin>>another_integer, cin will ignore \n or ' ' (whitespaces), but gets will not. What you are really typing is something like follows
5\n ---- see the end of line?
my string\n
my bigger string\n
gets() reads until it find a \n or end of file
by the way, gets() is deprecated in c++11, you should use getline() or other function instead
I highly recommend performing safer I/O using C++ constructs:
int main()
{
unsigned int quantity;
cin >> quantity;
// Now input the words
std::vector<std::string> database;
while (cin >> word)
{
database.push_back(word);
}
return 0;
}
Related
In the following code, getline() skips reading the first line.
I noted that when commenting the "cin >> T" line, it works normally. But I can't figure out the reason.
I want to read an integer before reading lines! How to fix that?
#include <iostream>
using namespace std;
int main () {
int T, i = 1;
string line;
cin >> T;
while (i <= T) {
getline(cin, line);
cout << i << ": " << line << endl;
i++;
}
return 0;
}
cin >> T;
This consumes the integer you provide on stdin.
The first time you call:
getline(cin, line)
...you consume the newline after your integer.
You can get cin to ignore the newline by adding the following line after cin >> T;:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
(You'll need #include <limits> for std::numeric_limits)
Most likely there is a newline in your input file, and that is being processed immediately, as explained on this page:
http://augustcouncil.com/~tgibson/tutorial/iotips.html
You may want to call cin.ignore() to have it reject one character, but, you may want to read more of the tips, as there are suggestions about how to handle reading in numbers.
This line only reads a number:
cin >> T;
If you want to parse user input you need to take into account they keep hitting <enter> because the input is buffered. To get around this somtimes it is simpler to read interactive input using getline. Then parse the content of the line.
std::string userInput;
std::getline(std::cin, userInput);
std::stringstream(userInput) >> T;
This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 6 years ago.
int main()
{
int t;
cin>>t;
while(t--)
{
string s;
getline(cin,s);
cout<<s.at(0);
}
return 0;
}
I tried to run this code but it says out_of_range error. This code is not even taking in the string input.
You are mixing line-based input with non-line-based input.
int main()
{
int t;
cin>>t;
When the user enters "123" and then presses the enter key, the "123" part of the input is parsed and ends up as the number 123 in t, but the linebreak resulting from the enter key will remain in the input buffer.
That's non-line-based input.
while(t--) {
string s;
getline(cin,s);
The std::getline function reads everything until a linebreak is encountered. The linebreak from above is still there, so a linebreak is encountered immediately and s remains empty.
That's line-based input.
std::getline also consumes the linebreak it has encountered, but this doesn't help you much anymore:
cout<<s.at(0);
s has size 0 and at(0) tries to access the 1st element. at is required to throw std::out_of_range_error when you try to access a non-existing element.
A good solution would be to switch exclusively to line-based input on the top input layer. Read everything as lines and parse the individual lines as required. Use std::stoi to convert a string to an integer number.
Here is an example:
#include <iostream>
#include <string>
int main()
{
std::string input;
std::getline(std::cin, input);
int t = std::stoi(input);
while(t--)
{
std::string s;
getline(std::cin, s);
std::cout << s.at(0);
}
}
Note that you should consider adding more error handling to your code. What happens when the user enters a negative number?
You can use cin.sync() function to clear extra input buffer.
The code like this:
int main()
{
int t;
cin >> t;
cin.sync(); // add this line
while(t--)
{
string s;
getline(cin, s);
cout<<s.at(0);
}
return 0;
}
The original code to make the string that is empty and you're trying to access the first element. So it says out_of_range error.
As I declared a structure array: struct name data[5];
When I try to take input using cin.getline(data[i].full_name,75) (which I need) then after first time it skips the char input. I searched on this site and used fgets but was of no use.
The code is :
#include<iostream>
using namespace std;
struct name
{
char full_name[75];
int number;
};
void input(struct name data[])
{
int i=0;
while(i<5)
{
cout<<"Enter the name: ";
fgets(data[i].full_name,75,stdin);
OR
cin.getline(data[i].full_name,75)
cout<<"Enter the number: ";
cin>>data[i].number;
i++;
}
}
int main()
{
int times=0;
struct name data[5];
input(data);
}
here is my suggestion hope it helps:
void input(struct name data[])
{
int i=0;
int number;
char asciNumber[75];
while(i<5)
{
cout<<"Enter the name: ";
cin.getline(data[i].full_name,75);
cout<<"Enter the number: ";
cin.getline(asciNumber,75);
try
{
number = atoi(asciNumber);
data[i].number = number;
}
catch (...)
{
//cout << "error in number parsing" << endl;
// i think its important to check validity of std input\
}
i++;
}
}
Well, for starters, you can't use fgets() here, at all. The results of mixing the C library's stdin-based functions, and C++ library's std::cin are undefined.
But your real problem is this:
cin>>data[i].number;
Your intent here is to read a line of text containing a number.
As you know, each line of text is terminated by a newline.
The >> operator will read the entered number, but it will not actually read the newline character that follows it.
As a result of that, on the next iteration of the loop:
cin.getline(data[i].full_name,75)
All this will do, then, is immediately read the newline character after the entered number, instead of the next line of text.
You will need to replace your usage of the >> operator with another getline() that reads the next line of text into a std::string, and then use std::istringstream to convert it to a number.
That's the cleanest implementation. There are a couple of other possibilities, such as manually reading past the newline character after the number, or another, throw-away call to std::getline().
This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 8 years ago.
Hi guys i am facing an unknown error while taking input from getline.My purpose is to take a number and two strings as input from the user and print the first string.Here is the problem code
#include <iostream>
using namespace std;
int main() {
int t;
cin>>t;
while(t--)
{ string s,p;
getline(cin,s);
getline(cin,p);
cout<<s;
}
return 0;
}
Now when i give input like:
1
abababa abb
b
it doesn’t print anything.Why is it happening?
After cin>>t, there is a newline remaining in the stream, then the newline will be assigned to s, so cout<<s seems to print nothing(Actually, it prints a newline).
add cin.ignore(100, '\n'); before first getline to ingore the newline.
Each time you use cin to get something like in cin >> t, it will leave a newline in the input buffer. so in next operation it will be affected by that and will seem to skip the "wait for return key" and hence abnormality. To avoid that usecin::ignore.
the documentation says:
Extracts characters from the input sequence and discards them, until
either n characters have been extracted, or one compares equal to
delim.
The function also stops extracting characters if the end-of-file is
reached. If this is reached prematurely (before either extracting n
characters or finding delim), the function sets the eofbit flag.
I have written your code in very understandable way but working
Let me know if you have any issue
#include <iostream>
using namespace std;
int main() {
int t=0;
cout<<"Enter t\n";
cin>>t;
cin.ignore();
while(t>0)
{ string s,p;
cout<<"Enter s\n";
getline(cin,s);
cout<<"Enter p\n";
getline(cin,p);
cout<<" Values s:"<<s<<" p:"<<p<<"\n";
t--;
}
return 0;
}
The newline from cin >> t; after pressing enter is still in std::cin when getline(cin,s) is called, resulting in s being empty. The string you enter is actually being stored in p. Try using a different capture method or flushing the cin buffer before using it again.
I think it's because getline() doesn't ignore the new line ccharacter, but it reads it in the next call yo getline. Try yo put a getline() before each calle, something like this:
Int main() {
int t;
cin>>t;
string s,p;
getline(cin,s);
while(t--)
{
getline(cin,s);
getline(cin, p);
getline(cin,p);
cout<<s;
}
Hope it helps :)
I know how to do this in C but have no idea for a C++ solution. I want the following to be fail safe, but after providing a string or even a char to the input, the program hangs. How to read input stream including \n to free it?
int main() {
int num;
do {
std::cin.clear();
std::cin >> num;
while ( std::cin.get() != '\n' );
} while ( !std::cin.good() || num > 5 );
return 0;
}
Once the stream is in an error state all read operations will fail. This means that, if the cin >> num read fails, the loop with the get() calls will never end: all those get()s will fail. Skipping to the end of the line can only be done after clearing the error state.
To build on top of R. Martinho Fernandes answer, here is a possible C++ alternative to your code:
std::string num;
std::getline(std::cin, num);
// Arbitrary logic, e.g.: remove non digit characters from num
num.erase(std::remove_if(num.begin(), num.end(),
std::not1(std::ptr_fun((int(*)(int))std::isdigit))), num.end());
std::stringstream ss(num);
ss >> n;
The std::getline function extracts characters from cin and stores to num. It also extracts and discards the delimiter at the end of the input (you can specify your own delimiter or \n will be used).
The string::erase function removes all characters but digits from the num string, using std::remove_if with a negative std::isdigit predicate.
The string is then represented as an integer using a std::stringstream (a boost::lexical_cast would have worked as well)
The logic here implemented by the erase function can be any other logic, but this code is probably much simpler to read than the one included in the question.
I would approach it using getline(cin,num) and then catch any fails using cin.fail(). I usually use cin.fail() with ints but theoretically should work with strings and chars also, for example :
string num;
getline(cin,num);
if(cin.fail())
{
cin.clear();
cin.ignore();
}
One way would be to check the state after every input and throw an exception if that happens
for example:
#include<iostream>
using namespace std;
int main(){
int a;
cout<<"Enter a number: ";
cin>>a;
//If a non number is entered, the stream goes into a fail state
try
{
if(cin.fail()){
throw 0;
cin.clear();
cin.ignore();
}
}
catch(int){
cin.clear();
cin.ignore();
}
return 0;
}
After that you can continue with whatever code you wish
To clear input stream, use cin.sync() .
no need to use cin.clear() or cin.ignore().