【问题标题】:Distinguishing between an int and a double区分 int 和 double
【发布时间】:2015-06-08 06:05:00
【问题描述】:

我已经搜索过这个答案,但似乎没有人知道如何解决这个错误。我希望输入严格地是一个 int。如果输入是双精度,我希望它发送错误。

int creatLegs = 0;
string trash;
bool validLegs = true;
do
{
    cout << "How many legs should the creature have? ";
    cin >> creatLegs;

    if(cin.fail())
    {
        cin.clear();
        cin >> trash; //sets to string, so that cin.ignore() ignores the whole string.
        cin.ignore(); //only ignores one character
        validLegs = false;
    }

    if (creatLegs > 0)
    {

        validLegs = true;
    }

    if (!validLegs)
    {
        cout << "Invalid value, try again.\n";
    }

} while (!validLegs);

它似乎几乎可以工作。它发送错误,但仅在进入下一个循环之后。我怎样才能解决这个问题?为什么它仍然显示错误消息但在显示之前仍然继续?

【问题讨论】:

  • 很抱歉,我不确定您的意思。不,它不会将其存储为 int。如果我输入不是 int 的内容,它不知道该怎么做。它吐出垃圾邮件,直到我添加了“if(cin.fail())”
  • cout en.cppreference.com/w/cpp/io/manip/endl

标签: c++ int double invalid-characters


【解决方案1】:

输入可以是整数或浮点数的表示以外的其他东西。

请记住,数字不是它们的表示形式:9(十进制)、017(八进制,à la C)、0b1001(二进制,à la Ocaml)、IX(罗马符号) 、8+1(算术表达式)、neuf(法语)都是同一个数字 9 的表示。

因此,您必须决定是否接受 9 x9 之类的输入(数字后有几个空格),...更一般地,您必须定义可接受的输入(以及如果输入是否在行尾结束,是否应接受空格或标点符号等...)。

您可以阅读整行(例如使用std::getline)并使用例如sscanf%n 控制格式很有用,sscanf 返回的项目计数也很有用)或std::stol(使用结束指针)来解析它

另请注意,您的问题(“区分 int 和 double”)的措辞是错误的。 C++ 中没有单一的“intdouble”类型(但 int 是标量类型,double 是 C++ 中的标量类型,您可以使用 tagged union 定义 class持有其中任何一个)。 AFAIU,如果您声明int x;,则使用std::cin &gt;&gt; x;,用户输入12.64 点和数字64 后不会被解析,x 将变为 12。

【讨论】:

  • 我现在只想坚持使用整数,以便了解它是如何工作的。我最好包括所有不同的方式来表示一个数字,但由于这只是一个简单的程序,我不想太深入。不过还是谢谢你。我不确定你在最后一部分说了什么。我是 C++ 编码的新手,如果您能为我稍微简化一下,我将不胜感激。
  • 请按照我给你的链接。我相信你会自己编写代码。而理解文档是软件开发中非常重要的一环,所以你需要学习如何阅读文档。玩得开心!
【解决方案2】:

我认为您应该将数据读取为字符串,然后逐个字符地检查它以验证它是整数 - 如果每个字符都是数字,那么我们就有整数,我们可以解析它。

流的问题是,如果您尝试读取整数但传递了十进制,它会读取直到点的数字。而这部分是一个适当的整数,所以cin.fail() 返回false

示例代码:

#include <iostream>
#include <string>
#include <cctype>
#include <cstdlib>

using namespace std;

int main() {
    int creatLegs = 0;
    bool validLegs = true;
    do
    {
        cout << "How many legs should the creature have? ";
        string input;
        getline(cin, input);

        validLegs = true;
        for (string::const_iterator i = input.begin(); validLegs && i != input.end(); ++i) {
            if (!isdigit(*i)) {
                validLegs = false;
            }
        }

        if (!validLegs)
        {
            cout << "Invalid value, try again.\n";
        } else {
            creatLegs = atoi(input.c_str());
        }

    } while (!validLegs);

    cout << creatLegs << endl;
}

这当然不是一个完美的解决方案。如果有任何前导或尾随空格(或任何其他字符,如+-),程序将失败。但如果需要,您始终可以添加一些代码来处理这些情况。

【讨论】:

【解决方案3】:
int creatLegs = 0;
do
{
    cout << "How many legs should the creature have? ";
    cin >> creatLegs;    // trying to get integer
    if(!cin.fail())      // if cin.fail == false, then we got an int and leave loop
        break;
    cout << "Invalid value, try again.\n"; // else show err msg and try once more
    cin.clear();
} while (1);

【讨论】:

  • 这不会拒绝 1.23 作为输入
  • 当我输入一个字母时我的程序崩溃了。我现在设置它的方式是,在输入字母时会发送错误。
【解决方案4】:

这个问题已经有一个公认的答案,但是我将提供一个解决方案来处理所有整数,即使是那些表示为浮点数(没有小数部分)的数字,并拒绝包含除数字后面的空格。

接受值的例子,这些都代表数字4:

4
4.
4.0
+4
004.0
400e-2

拒绝值示例:

3.999999
4.000001
40e-1x
4,
#include <iostream>
#include <sstream>
#include <cctype>
#include <string>

using namespace std;

bool get_int( const string & input, int & i ) {
    stringstream ss(input);
    double d;
    bool isValid = ss >> d;
    if (isValid) {
        char c;
        while( isValid && ss >> c ) isValid = isspace(c);
        if (isValid) { 
            i = static_cast<int>(d);
            isValid = (d == static_cast<double>(i));
        }
    }
    return isValid;
}

int main( int argc, char *argv[] )
{
    int creatLegs = 0;
    bool validLegs = false;

    do
    {
        string line;
        do {
            cout << "How many legs should the creature have? ";
        } while (not getline (cin,line));

        validLegs = get_int( line, creatLegs );

        if (creatLegs <= 0)
        {
            validLegs = false;
        }

        if (not validLegs)
        {
            cout << "Invalid value, try again." << endl;
        }

    } while (not validLegs);

    cout << "Got legs! (" << creatLegs << ")" << endl;

    return 0;
}

如果你想要严格的整数(没有小数点和科学记数法),那么使用这个更简单的 get_int 函数:

bool get_int( const string & input, int & i ) {
    stringstream ss(input);
    bool isValid = ss >> i;
    if (isValid) {
        char c;
        while(isValid && ss >> c) isValid = isspace(c);
    }
    return isValid;
}

【讨论】:

    猜你喜欢
    • 2016-01-21
    • 2014-06-26
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多