简体   繁体   中英

Why is the input stream not recognizing Ctrl D and gives an infinite loop instead?

I'm trying to read in the characters typed in by the user until Ctrl+ D has been pressed. When executing my code, the loop seems to infinitely run alternating between the outputs of "Please enter strings and press Ctrl +D to quit" and "Exciting Function". Is there a way I can errorhandle this input better?

I try changing the while condition to getLine(cin,input),but to no avail. I'm considering using an inputstream though.

//get the user input. return true if all the strings are made of only alphanumeric characters
bool getUserStrings(vector<string>& usrVec)
{
    string input;
    vector<string>::iterator lp;
    string::iterator lp2;
    cout << "Please enter strings and press Ctrl D to quit" << endl;
    while (cin >> input)
    {
        usrVec.push_back(input);
    }

    for (lp = usrVec.begin(); lp != usrVec.end(); lp++)
    {
        for (lp2 = lp->begin(); lp2 != lp->end(); ++lp2)
        {
            if (*lp2 < 'A' || *lp2 > 'Z' || *lp2 < 'a' || *lp2 > 'z'
                || *lp2 < '0' || *lp2 > '9')
            {
                cout << "Exciting function" << endl;
                return false;
            }
        }
    }

    cout << "Happy Function" << endl;
    return true;
}

int main()
{
    vector<string> userStrings;
    while (!getUserStrings(userStrings))
}

Your problem is that you return true even if input is empty. You might be able to solve this in several ways, but my way is to flush standard input.

if (cin.eof()) {
    cin.clear();
    cin.ignore(input.size());                                             
}

I would put it after your outer for() loop.

The problem is this line of code:

while (!getUserStrings(userStrings));

Your program properly detects the Ctrl-D input with this line of code:

while (std::cin >> input)

However, getUsersStrings is returning false. The ! turns that into a true and the code goes into an infinite loop

Simply change

while (!getUserStrings(userStrings));

to

while (getUserStrings(userStrings));

Alternative solution: There really is no need to scan to make sure that a non-alpha numeric input has been given. On Unix systems, Ctrl-D is interpreted as EOF. The while(cin >> input) input will stop when EOF is reached, which is when a Ctrl - D is reached, so no need to scan for a non-alphanum after the loop has exited. The code could be written as follows:

#include <iostream>
#include <string>
#include <vector>
//get the user input. return true if all the strings are made of only alphanumeric characters

bool getUserStrings(std::vector<std::string>& usrVec)
{

  std::string input;
  std::vector<std::string>::iterator lp;
  std::string::iterator lp2;    
  std::cout << "Please enter strings and press Ctrl D to quit" << std::endl;
  while (std::getline(std::cin, input)) {
    usrVec.push_back(input);
  }

  std::cout << "Exiting function" << std::endl;
  std::cout << "Happy Function" << std::endl;

  return false;
}

int main()
{
  std::vector<std::string> userStrings;

  while (getUserStrings(userStrings));
}

The condition on cin is not the problem. You populate userStrings with the input and if it contains something you don't like, you return false and run the function again. With the bad string still present in userStrings. You probably want to discard the wrong inputs at some point I guess?

And your if condition for bad characters looks like it would fire on every character imaginable, you may need to put some && and parens in there. (ok, I see you noticed in the comments, it would be better to edit the question)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM