C++ cin.clear() 和 cin.ignore(...) 问题

标签 c++ visual-c++ input cin

因此,我有几个字段需要用数字填写。如果我尝试用字母填写输入(例如“noway”或“gg1337” - 它会出错并要求输入有效数字(没有字母例如“13”或“1500000”)。

但是有一个问题,如果我开始用数字填充输入然后添加一些字母(例如“12nowshithappens”),这会跳转到下一个输入字段,认为它是一个有效数字,但是在下一个输入字段中显示错误。

函数代码如下:

int appled()
{   
    cin >> appleds;
    while(cin.fail())
    {       
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(),'\n');
        cout << "An arror occured!\nPlease, enter a valid number: ";
        cin >> appleds;
    }
    return appleds;
}

如果我描述的有误——这里是我的测试程序的完整代码:)

// exZerry presents 

#include <iostream>
#include <conio.h>

int apples;
int fruit;
int oranges;
int x;
int appleds;
int orangeds;

using std::cout;
using std::cin;
using std::endl;
using std::numeric_limits;
using std::streamsize;

char newline = '\n';

bool ok;    
bool ok2;   
bool ok3;

int appled() //Function to receive 'apples' input
{   
    cin >> appleds;
    while(cin.fail())
    {       
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(),'\n');
        cout << "An arror occured!\nPlease, enter a valid number: ";
        cin >> appleds;
    }
    return appleds;
}
int oranged() //Function to receive 'oranges' input
{   
    cin >> orangeds;
    while(cin.fail())
    {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(),'\n');
        cout << "An arror occured!\nPlease, enter a valid number: ";        
        cin >> orangeds;
    }
    return orangeds;
}

int main()
{
    ok = ok2 = ok3 = false; //Some testing
    while(!ok2) //Actual program loop
    {       
        x = 0; // Dropping program restart.
        //cout << "-----------------------" << endl;
        //cout << "DEBUG MODE: " << x << endl;
        //cout << "-----------------------" << endl;
        cout << "=====================================================" << endl;
        cout << "Enter apples: ";
        apples = appled();
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(),'\n'); //Now we have apples
        cout << "Enter oranges: ";      
        apples = oranged();
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(),'\n'); //And now we have oranges
        cout << "\n=====================================================" << endl;
        cout << "Calculating..." << endl;
        cout << "=====================================================" << endl;
        fruit = apples + oranges;
        cout << "In total we have " << fruit << " fruit" << endl;
        cout << "=====================================================" << endl;
        cout << newline;
        //Option to go out or continue the loop
        //If you enter 1 - resets the program, any other char - exit
        cout << "Go out? (1 - 'No', Others - 'Yeap'):" << "  "; 
        cin >> x;
        cout << newline;
        // ok2 = true;
        if (x == 1) 
        {
            cout << "Continue the program..." << endl;
            //cout << "-----------------------" << endl;
            //cout << "DEBUG MODE: " << x << endl;
            //cout << "-----------------------" << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(),'\n');
            ok = false;
            ok3 = false;
            continue;
        }
        if (x == 0)
        {
            cout << "Shutting down the app..." << x << endl;
            //cout << "-----------------------" << endl;
            //cout << "DEBUG MODE: " << x << endl;
            //cout << "-----------------------" << endl;
            break;
        }
        else 
        {
            cout << "Shutting down the app..." << x << endl;
            //cout << "-----------------------" << endl;
            //cout << "DEBUG MODE: " << x << endl;
            //cout << "-----------------------" << endl;
            break;      
        }
    }
    cout << "Press any key to exit :D" << endl;
    getch();
    return 0;
}

最佳答案

您可以使自己的解析字符序列的切面像添加无效一样。像这样:

class num_get : public std::num_get<char>
{
public:
    iter_type do_get( iter_type it, iter_type end, std::ios_base& str,
                      std::ios_base::iostate& err, long& v) const
    {
        auto& ctype = std::use_facet<std::ctype<char>>(str.getloc());
        it = std::num_get<char>::do_get(it, end, str, err, v);

        if (it != end && !(err & std::ios_base::failbit)
                      && ctype.is(ctype.alpha, *it))
            err |= std::ios_base::failbit;

        return it;
    }
};

现在您可以将它安装到您的流中:

std::locale orig(std::cin.getloc());
std::cin.imbue(std::locale(orig, new num_get));

while (!(std::cin >> appleds)) {
    // input was not entirely numeric
}

// input was entirely numeric

关于C++ cin.clear() 和 cin.ignore(...) 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25768522/

相关文章:

C++ 数组对坐标周围的值求和

c++ - 谁取得 IErrorInfo 的所有权?

visual-studio - 我可以使用较新版本的 Visual Studio 来做 "old"的事情吗?

c++ - 我如何在 VC++7 及更早版本中模拟 _set_abort_behavior?

c++ - 如何在不等待输入的情况下使用 getch()?

html - 输入和 Div 匹配高度

c++ - 数组元素编号

c++ - static const int 作为 map 下标

c++ - 无法在函数中声明模板化类型别名

Jquery 输入值是否工作