C ++中的输入验证和溢出

input validation and overflow in c++

我正在编写一个代码,它接受用户的输入并根据用户购买的单位数量计算折扣。这是我的问题;我想使用输入验证来确保输入的数字在 0 到 65535 之间(unsigned int 的最大范围)但是我设置这个程序的方式,如果用户输入的数字超出了我遇到的这个范围overflow/underflow 并且在变量到达 if/else 子句之前就将不正确的数字存储在变量中。我是 C++ 的新手,所以请善待。当用户输入这个数字时,我该怎么做才能检查它是否在正确的范围内。另外,有没有办法验证用户没有输入数字以外的字符? 这是我的代码:

#include<iostream>
#include<iomanip>

using namespace std;

int main()
{
    // display the instructions and inform the user of the discounts available

    cout << " This software package sells for . Discounts are given according to the following list: \n";
    cout << "----------------------------------" << endl;
    cout << " Quantity\t\t Discount" << endl;
    cout << "----------------------------------" << endl;
    cout << " 10 - 19\t\t 20%" << endl;
    cout << " 20 - 49\t\t 30%" << endl;
    cout << " 50 - 99\t\t 40%" << endl;
    cout << " 100 or more\t\t 50%" << endl;
    cout << "----------------------------------" << endl;
    cout << "\n\n";

    const double price = 99.00;

    unsigned short quantity;  // variable to hold the user's quantity. 
                              // shouldn't need more than 2 bytes for this (unsigned short)

    cout << "How many units are sold?: ";
    cin >> quantity;

    double discount; // variable to hold the amount discounted
    double total; // to hold the total sales price

    cout << fixed << showpoint << setprecision(2); // set the display of numeric values

    // calculate the discounted prices

    if (quantity >= 1 && quantity <= 9) {

        total = quantity * price; // calculate the total without a discount

        cout << "There is no discount for this order \n";
        cout << quantity << " units were sold at $" << price << " a piece for a total of " << total << endl;
        cout << "\n";
    }
    else if (quantity >= 10 && quantity <= 19) {

        discount = (quantity * price) * .20; // calculate the discount
        total = (quantity * price) - discount; // calculate the total

        cout << "There is a 20% discount \n";
        cout << quantity << " units were sold at $" << price << " with a discount of 20% applied to the order. \n";
        cout << "The total cost of the sale is $" << total << endl;
        cout << "\n";
    }
    else if (quantity >= 20 && quantity <= 49) {

        discount = (quantity * price) * .30; // calculate the discount
        total = (quantity * price) - discount; // calculate the total

        cout << "There is a 30% discount \n";
        cout << quantity << " units were sold at $" << price << " with a discount of 30% applied to the order. \n";
        cout << "The total cost of the sale is $" << total << endl;
        cout << "\n";
    }
    else if (quantity >= 50 && quantity <= 99) {

        discount = (quantity * price) * .40; // calculate the discount
        total = (quantity * price) - discount; // calculate the total

        cout << "There is a 40% discount \n";
        cout << quantity << " units were sold at $" << price << " with a discount of 40% applied to the order. \n";
        cout << "The total cost of the sale is $" << total << endl;
        cout << "\n";
    }
    else if(quantity > 99 && quantity <= 65535) {

        // the maximum number allowed in a short int is 65535. I is unrealistic that someone would order more 
        // units than that so this else if clause checks to make sure the number of ordered items is below this number

        discount = (quantity * price) * .50; // calculate the discount
        total = (quantity * price) - discount; // calculate the total

        cout << "There is a 50% discount \n";
        cout << quantity << " units were sold at $" << price << " with a discount of 50% applied to the order. \n";
        cout << "The total cost of the sale is $" << total << endl;
        cout << "\n";
    }
    else {

        // the trailing else clause is used to catch any value for quantity that is 0 or below or any quantity
        // bigger than what a short int can hold. 

        cout << "You entered an invalid quantity.\n";
        cout << "Please enter a value greater than 0 or less than 65,535. \n\n";
    }




    system("pause");
    return 0;
}

最后的 else 子句仅在输入值 0 时执行。这是一个值超出范围

的输出示例
 This software package sells for . Discounts are given according to the following list:
----------------------------------
 Quantity                Discount
----------------------------------
 10 - 19                 20%
 20 - 49                 30%
 50 - 99                 40%
 100 or more             50%
----------------------------------


How many units are sold?: 65600
There is a 50% discount
52428 units were sold at .00 with a discount of 50% applied to the order.
The total cost of the sale is 95186.00

Press any key to continue . . .

老实说,我不认为这是一个糟糕的问题。 它只处理错误检查来自 cin >> quantity.

的任何内容

如此处所述:User Input of Integers - Error Handling,一种处理此问题的方法是使用如下错误处理代码包装 cin >> quantity

if (cin >> quantity) {
   // read succeeded
} else if (cin.bad()) {
   // IO error
} else if (cin.eof()) {
   // EOF reached (perhaps combined with a format problem)
} else {
   // format problem
}

然而,这不会处理整数溢出,因此完整的解决方案是将 quantity 设为 int 并使用

cout << "How many units are sold?: ";
if (cin >> quantity) {
    // read succeeded

    // check for range
    if (quantity < 0 || quantity > 65535) {
        cout << "Number needs to be between 0 and 65535" << endl;
        return -1;
    }
} else if (cin.bad()) {
    // IO error
    cout << "Couldn't do a read from stdin :(" << endl;
    return -1;
} else if (cin.eof()) {
    // EOF reached (perhaps combined with a format problem)
    cout << "Stdin gave EOF :(" << endl;
    return -1;
} else {
    // format problem
    cout << "Encountered incorrect format" << endl;
    return -1;
}