(C++)如何检查输入字符串是否为整数

(C++) How to check whether or not an input string is an integer?

本文关键字:字符串 是否 整数 输入 C++ 何检查 检查      更新时间:2023-10-16

我希望此代码检查输入是否为int,并且在输入浮点类型的数字之前,它可以正常工作。我需要一个不会让浮点数通过的程序。

bool error;
int x;
string s;
do
{
    cout <<"number: ";
    cin >> x;
    error=cin.fail();
    if(error)
    {
        cout << "error" <<endl;
        cin.clear();
    }
    getline(cin,s);
}while(error);
cout << x;

将用户的所有输入行作为字符串读取,然后使用std::stoi将字符串转换为整数。

不幸的是,当std::stoi到达可转换字符的末尾时,它会很高兴地停止转换,但它允许您将指针传递到要用结束转换的字符更新的位置。如果这个位置不是字符串的末尾,那么这行就有垃圾。

bool error = true; // assume user input is wrong
while (error)
{    
    if (std::getline(std::cin, s)) // grab the whole line 
    {
        std::size_t end;
        try
        {
            x = std::stoi(s, &end);
            if (end == s.length()) // converted all user input
            {
                error == false; // good data
            }
        }
        catch(std::invalid_argument &) // user input is complete garbage
        {
        }
        catch(std::std::out_of_range &) // converted user input is too big for int.
        {
        }
    }
}
                                  ^ 

我建议把输入循环变成一个函数。1) 如果您需要再次转换int,它很容易重复使用。2) 它去掉了上面的一些逻辑,因为当输入经过测试并且良好时,您可以return

int gimmieInt(std::istream& in) // Me eat input stream! Om nom nom nom!
{
    std::string s;
    int x;
    while (true) // consider instead using a maximum number of retries. 
                 // This increases complexity, so consider it *after* you have 
                 // the basic version working 
    {    
        if (std::getline(in, s)) 
        {
            std::size_t end;
            try
            {
                x = std::stoi(s, &end);
                if (end == s.length()) 
                {
                    return x; 
                }
            }
            catch(std::invalid_argument &) // user input is complete garbage
            {
            }
            catch(std::std::out_of_range &) // user input is too big for int.
            {
            }
        }
    }
}

std::istream& operator(std::istream&, int)将读取一个有效的整数,直到任何不匹配的字符,如'.',并且到目前为止,流没有设置错误状态。

您最好将完整的(空格分隔)块读取为std::string,并检查它们是否包含所需的格式(例如使用std::regex)。

如果您试图转换区块,std::stoi()也应该失败,并出现异常。

我认为,您正在寻找这样的东西(C++11):

auto s = std::string{};
std::cin >> s;
if( std::all_of(std::begin(s), std::end(s),
                [](char c) -> bool {
                    return c <= '0' && c <= '9';
                }) ) {
    std::cout << "you have entered an integer" << std::endl;
}

不知怎的,我想,标准库包含一个谓词,用于检查给定的字符是否是数字,但我现在找不到它。这样的假设is_digit()将使代码更可读:

if( std::all_of(std::begin(s), std::end(s), std::hypothetic::is_digit) ) {
    std::cout << "you have entered an integer" << std::endl;
}