0

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?

Linkon
  • 1,058
  • 1
  • 12
  • 15
  • 1
    Why would you even consider using gets()? http://stackoverflow.com/questions/30890696/why-gets-is-deprecated –  Mar 15 '17 at 18:09
  • Don't use `gets` in C++. It is deprecated in C++11 and removed in C++14 and beyond. – NathanOliver Mar 15 '17 at 18:10
  • The `gets` function is dangerous, as it can overflow buffers. If you must, use `fgets` instead. Prefer to use `std::string` in C++ for text. – Thomas Matthews Mar 15 '17 at 18:11
  • Because i have to take input two lines where each line contains five words. – Linkon Mar 15 '17 at 18:11
  • Your `main` function should return a value to the operating system, such as 0 for success, other numbers for failure. – Thomas Matthews Mar 15 '17 at 18:12
  • You should be using `std::string` to read in words and `std::vector` to store the words. Try this: `std::string word; std::cin >> word;`. – Thomas Matthews Mar 15 '17 at 18:13
  • sorry, i can't understand your explanation. – Linkon Mar 15 '17 at 18:13
  • @Thomas "Your main function should return a value to the operating system" - I would have thought that someone that posts so much stuff here would know this isn't necessary in C++. –  Mar 15 '17 at 18:13
  • thank you, i know this. but why this happening for just using one gets() function outside . – Linkon Mar 15 '17 at 18:15

3 Answers3

2
  1. Don't use gets. See Why gets() is deprecated?.
  2. 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.

Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • "Don't mix cin and functions from stdio.h." Please say exactly why not - technically it's perfectly safe; much C++ code would not work if it wasn't. –  Mar 15 '17 at 18:20
  • Do you recommend reading a whole line, when the requirement is for a word? – Thomas Matthews Mar 15 '17 at 18:21
  • @ThomasMatthews, no, I don't. I didn't think I was making that recommendation. – R Sahu Mar 15 '17 at 18:34
0

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

Moro Silverio
  • 87
  • 2
  • 7
0

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;
}
Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154