0

I want to write a program which prints Real Fancy if the given string contains "NOT" or "not" and regularly fancy if it doesn't contain not.

Ex: "this is not a string" o/p: Real Fancy

"this is nothing" o/p: regularly fancy

The problem is it prints Real Fancy if my first testcase input is "not is this line". But if the same line is given as input in second or above testcase it is not working and printing regularly fancy.Why? Any help?

Here is the code:

#include <bits/stdc++.h>


using namespace std;

int main()
 {

   int t;//No.of test cases

   cin>>t;

   while(t--)
   {
    string quote;//the input from user
    string found="not";//word to be found
    string temp="";
    int not_found=0;
    cin.ignore();
    getline(cin,quote);

    //Splitting the given line into words and store in a vector
    vector<string> words;
    istringstream iss(quote);
    copy(istream_iterator<string>(iss),
    istream_iterator<string>(),
    back_inserter(words));

   //Scan for "not" and if found break from for loop
    for(int i=0;i<words.size();i++)
    {
        temp=words[i];
        transform(temp.begin(),temp.end(),temp.begin(),::tolower);
        if(temp==found)
        {
            cout<<"Real Fancy"<<endl;
            not_found=1;
            break;
        }
       }
      if(not_found==0)
        cout<<"regularly fancy"<<endl;

    }

    return 0;
 }
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • yes. Actually the first letter is missing in the 'first word' of vector after first input. Like '**This** is not' in words is {**his**,is,not}. I don't know why is this happening. –  Jan 07 '19 at 17:36
  • 1
    Regarding `int t;//No.of test cases`, instead of having to comment, consider giving `t` a descriptive name. – user4581301 Jan 07 '19 at 17:40
  • Do not use `#include – user4581301 Jan 07 '19 at 17:47

1 Answers1

0

The input pattern looks like

t
quote
quote
quote
...

The reading of t

cin>>t;

stops as soon as it finds an input that cannot possibly be an integer. This includes the newline character representing the end of the line, leaving the newline character in the stream to be consumed later (see Why does std::getline() skip input after a formatted extraction? for more on that problem). The skipping problem has been resolved with a

cin.ignore();
getline(cin,quote);

in the while loop, but that traded one bug for another. If there was no preceding formatted input to leave unwanted characters in the stream, cin.ignore(); will be throwing out the legitimate first character of the input.

This will happen on the second and subsequent reads. The input will wind up looking like

t //newline consumed by ignore
quote //newline consumed by getline. ignore consumes first character of next line
uote //newline consumed by getline. ignore consumes first character of next line
uote //newline consumed by getline. ignore consumes first character of next line
..

Solution:

Move it to after the input that leaves the unwanted character in the stream

cin>>t;
cin.ignore();

A better alternative is to the ignore so that you can make certain you get rid of all potential garbage on the end of the line

cin>>t;
cin.ignore(numeric_limits<streamsize>::max(), '\n');

This will read from the stream up to the maximum possible length of the stream or a newline is found and discarded, whichever comes first.

Always clean up after an operation rather than before the next. It keeps the related code closer together, aiding in readability, and protects you from cases where there is nothing from before to clean up.

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • yeah. it's working. but why? what difference does it make if i use `cin.ignore()` before or in the `while` loop? I thought we have to clean up after every iteration? –  Jan 07 '19 at 17:42
  • @VishnuVardhanSistla Updated answer to better explain the problem – user4581301 Jan 07 '19 at 18:03