【问题标题】:Reading 'unsigned int' using 'cin'使用 'cin' 读取 'unsigned int'
【发布时间】:2012-03-23 09:42:20
【问题描述】:

我正在尝试使用cin 读取unsigned int,如下所示:

#include <limits.h>
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
    unsigned int number;

    // UINT_MAX = 4294967295
    cout << "Please enter a number between 0 and " << UINT_MAX << ":" << endl;

    cin >> number;

    // Check if the number is a valid unsigned integer
    if ((number < 0) || ((unsigned int)number > UINT_MAX))
    {
        cout << "Invalid number." << endl;
        return -1;
    }
    return 0;
}

但是,每当我输入一个大于无符号整数上限 (UINT_MAX) 的值时,程序就会显示3435973836。如何检查用户给出的输入是否介于 0UINT_MAX 之间?

【问题讨论】:

  • if ((number &lt; 0) || ((unsigned int)number &gt; UINT_MAX)) 我什至无法形容这是多么误导。
  • 也许从更简单的开始,绝对是一本好书。
  • 相当基本但合理的问题要问。但解释起来很长。
  • 如果它不适用于 Long,我建议您尝试使用 char 数组并将其转换为 unsigned int。

标签: c++ windows int unsigned cin


【解决方案1】:

您可以读入 unsigned long long 并根据 unsigned int 限制对其进行测试。

【讨论】:

  • @BoPersson,你是说&gt;&gt; 自动升级为long long?即使是这样,在存储在 unsigned int 中时也需要截断。
  • 我是说operator&gt;&gt; 正在使用num_get 收集字符,转换为最大的无符号整数类型,然后在分配结果之前验证目标范围。就像你自己做的那样。
【解决方案2】:

当用户输入高于UINT_MAX 的数字时,cin大写无论如何都会在UINT_MAX。该值也不能为负数。

如果需要扩展范围,使用unsigned long long作为输入,检查后强制转换为unsigned int。不过,这不会防止超出unsigned long long 范围的数字。

对于通用解决方案,您可以阅读string,并使用unsigned long long 作为结果自行进行转换。

【讨论】:

    【解决方案3】:

    您的检查没有意义(正确启用警告的编译器会告诉您)因为您的值永远不会低于 0 也永远不会超过 UINT_MAX,因为它们是 unsigned int 类型的变量的最小值和最大值(其中数字是)可以容纳。

    使用流状态来确定读入整数是否正常工作。

    【讨论】:

      【解决方案4】:

      如果您尝试将其读入unsigned int,您将不得不将自己限制在unsigned int 的约束中。

      执行您要求的最通用方法是将输入读取为string 并对其进行解析以确保它在正确的范围内。验证后,您可以将其转换为 unsigned int

      【讨论】:

        【解决方案5】:

        两件事:

        • 检查无符号整数是否为 UINT_MAX 是没有意义的,因为它永远无法达到该值!您的编译器可能已经抱怨“由于类型范围有限,比较总是错误的”之类的警告。

        • 我能想到的唯一解决方案是捕获字符串中的输入,然后使用老式的 strtoul() 设置 errno 以防溢出。

        即:

        #include <stdlib.h>
        
        unsigned long number;
        std::string numbuf;
        cin >> numbuf;
        number = strtoul(numbuf.c_str(), 0, 10);
        if (ULONG_MAX == number && ERANGE == errno)
        {
            std::cerr << "Number too big!" << std::endl;
        }
        

        注意:strtoul 返回一个无符号长整数;没有函数 strtou(),返回一个无符号整数。

        【讨论】:

        • 在调用之前最好将 errno 设置为 0,然后检查任何非零值。看来至少 EINVAL 也可能发生。
        猜你喜欢
        • 2015-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-13
        • 2011-11-22
        • 1970-01-01
        相关资源
        最近更新 更多