0

我需要防止缓冲区中留下的垃圾在输入开关盒菜单的值时被用于由用户输入的菜单调用的函数中。

菜单代码

void menu()
{
bool done = false; 
string input;
while(!done)
{
    cout << "Welcome to the DVD database." << endl;
    cout << "1. Add A DVD" << endl;
    cout << "2. Delete a DVD." << endl;
    cout << "3. Edit a DVD." << endl;
    cout << "4. List By Category." << endl;
    cout << "5. Retrieve by a DVD by Title." << endl;
    cout << "6. Display collection by year" << endl;
    cout << "7. Display collection by title" << endl;
    cout << "-999. Exit program" << endl;
    cout << "Please choose an option by entering the corresponding number" << endl;
    cin >> input;
    int value = atoi(input.c_str());
    switch(value)
    {
        case 1:addDVD(); break;
        case 2:deleteDVD(); break;
       // case 3:editDVD(); break;
        case 4:listByCategory();break;
        case 6:displayByYear();break;
        case 7:displayByTitle();break;
        case -999: writeToFile(); exit(0); break;
        default : cout <<"Invalid entry"<< endl; break;
    }
}
}

void retrieveByTitle()
{
string search;
int size = database.size();
int index = 0;
bool found = false;
cin.ignore();
cout << "Please enter the title of the DVD you would like to retrieve: " << endl;
getline(cin,search);
cout << search;
while(!found && index<size)
{
    if(database.at(index)->getTitle().compare(search)==0)
    {
        cout << database.at(index)->toString();
        break;
    }
}
cout << endl;
}

如果在菜单中输入 5,程序将跳过方法中的用户输入

4

2 回答 2

0

与交互式用户打交道时输入时,您应该使用 std::getline()

每次按 <enter> 时,std::cin 都会刷新到应用程序。所以这是你应该从用户那里读取数据的逻辑垃圾。

std::string answer;
std::cout << "Question:\n";
std::getline(std::cin, answer);

这将为您提供用户为响应上一个问题而提供的所有内容。

一旦你有了输入,你应该得到你认为输入的值。一旦你有了这个,你应该检查输入中是否有任何其他垃圾(如果有然后中止并重试),否则验证你期望的数据。

如果你期望一个整数;

std::stringstream linestream(answer);
int               value;
std::string       junk;

if ((answer >> value)) && (!(answer >> junk)))
{
    // If you got data
    // and there was no junk on the line you are now good to go
}

在您的具体示例中,已经有一种简单的方法可以做到这一点:

std::getline(std::cin, input);
int value = boost::lexical_cast<int>(input);  // throws an exception if there is not
                                              // an int on the input (with no junk)
于 2013-01-14T03:10:29.593 回答
0

此代码有效,但是如果您消除“ cin.ignore() ”,它会遇到您描述的相同问题,这会删除被 cin >> 运算符忽略的额外分隔符:

#include <iostream>
#include <climits>
using namespace std;

int main() {
    string a, b;
    while (true) {

        cout << "write 'x' to exit: " << endl;
        cin >> a;
        if (a == "x") {
            break;
        }       
        cout << "read '" << a << "'" << endl;

        cout << "now write a line: " << endl;
        cin.clear();          // clears cin status
        cin.ignore(INT_MAX);  // clears existing, unprocessed input

        getline(cin, a);
        cout << "read '" << a << "'" << endl;
    }

    return 0;
}
于 2013-01-13T23:14:36.530 回答