首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >只接受用户的数字输入

只接受用户的数字输入
EN

Stack Overflow用户
提问于 2021-07-27 11:58:02
回答 2查看 303关注 0票数 1

目前,我只接受程序中用户的数字输入。我做了很多研究,但是给出的所有示例代码仍然可以接受输入,比如10abc

这是一个英尺对米转换器。

代码语言:javascript
代码运行次数:0
运行
复制
include <iostream>
using namespace std;

bool isNumber(string feet){
    for (int i = 0; i < feet.length(); i++){
        if (isdigit(feet[i]) == false){
            return false;
        }
    return true;
    }
}

int main(){
    string feet;
    beginning:
    cout << "Enter the feet: ";
    cin >> feet;

    if (isNumber(feet))
        cout << "The meter is: " << (double)stod(feet) * 0.3048 << endl;
    else {
        cout << "Invalid input. Please try again" << endl;
        goto beginning;
    }
    return 0;
}

这段代码接近完美,但它不接受小数点(无语面),因为小数点会破坏“等位数”函数。

那么,是否有任何方法只接受纯数字,也包括小数点?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-07-27 20:41:21

那么,是否有任何方法只接受纯数字,也包括小数点?

函数std::strspn将返回仅包含在另一个字符串中的字符的字符串的长度。因此,如果希望同时允许小数位数和小数点,可以使用以下方法进行输入验证:

代码语言:javascript
代码运行次数:0
运行
复制
bool isNumber( string feet )
{
    return strspn( feet.c_str(), "0123456789." ) == feet.length();
}

但是,正如注释部分已经指出的那样,转换函数std::stod本身提供了可用于输入验证的信息。如果为该函数提供第二个参数,它将向提供的变量写入匹配的字符数。

函数std::stod在转换值之前会自动使用所有前导空格字符(例如空格和制表符)。如果还希望也允许尾随空格字符,但不允许使用其他类型的字符,则可能需要使用以下代码:

代码语言:javascript
代码运行次数:0
运行
复制
std::size pos;
double d;

//attempt the conversion
d = stod( feet, &pos );

//make sure that at least one character was converted
if ( pos == 0 )
    throw "Input was invalid!";

//make sure that all remaining characters are whitespace
while ( feet[pos] != '\0' )
{
    if ( !isspace( (unsigned char)feet[pos] ) )
        throw "Input was invalid!";
    pos++;
}

如果您根本不想允许任何空格,包括前导空格,那么在将字符串内容传递给std::stod之前,您必须自己验证字符串内容。

您可能想知道为什么我要将char转换为unsigned char。请参阅this question了解为什么需要这样做的原因。出于同样的原因,代码中的以下一行是错误的:

if (isdigit(feet[i]) == false){

应改为:

if (isdigit((unsigned char)feet[i]) == false){

此外,代码中的下列问题似乎值得一提:

线

cin >> feet;

将读取一个单词的输入。因此,如果用户输入例如2318 sijslnej,那么这一行代码将只将2318写到feet中。我怀疑这是你想要的。您可能需要使用feet.getline,因为它将读取整行,而不是只读第一个单词。

我强烈建议你戒掉写这个的习惯:

if ( isdigit(...) == false )

尽管这一行总是有效的,但它仍然是一个非常坏的习惯,因为这个习惯也会导致您写以下内容:

if ( isdigit(...) == true )

这一行相当于

if ( isdigit(...) == 1 )

这是错误的。函数std::isdigit返回int类型的值,而不是bool类型,并且返回值不一定是01。它可以返回任何非零值来表示一个数字,例如20。在这种情况下,上面提到的if条件表达式将等价于20 == 1,后者将计算为false。这不是你想要的。

因此,而不是

if ( isdigit(...) == false )

你应该写

if ( !isdigit(...) )

而不是

if ( isdigit(...) == true )

你应该写:

if ( isdigit(...) )

票数 2
EN

Stack Overflow用户

发布于 2021-07-27 12:08:50

代码语言:javascript
代码运行次数:0
运行
复制
template <typename T>
T readFromLine(std::istream& in)
{
    std::string line;
    while (std::getline(in, line)) { // read whole line until it is possible
        std::istringstream line_stream { line }; // initialize string stream to parse line read
        T x;

        // try read `x` then discard white spaces then check if end of lien was reached
        if (line_stream >> x >> std::ws && line_stream.eof()) {
            // stop since reading was successful and line do not contain anything extra
            return x;
        }
        // continue if reading `x` was unsuccessful or when line contains something extra
    }
    // while loop ended since end of file was reached or error on input stream
    throw std::invalid_argument { "stream to short" };
}

https://godbolt.org/z/75efEP9Y8

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68544396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档