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

input validation and overflow in c++

本文关键字:溢出 验证 输入 c++      更新时间:2023-10-16

我正在编写一个代码,该代码接受用户的输入,并根据用户购买的单位数量计算折扣。这是我的问题;我想使用输入验证来确保输入的数字在0和65535之间(unsigned int的最大范围),但我设置这个程序的方式,如果用户在这个范围之外输入一个数字,我正在经历溢出/下流,并且在它甚至击中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 $99. Discounts are given according to the following list: n";
    cout << "----------------------------------" << endl;
    cout << " Quantitytt Discount" << endl;
    cout << "----------------------------------" << endl;
    cout << " 10 - 19tt 20%" << endl;
    cout << " 20 - 49tt 30%" << endl;
    cout << " 50 - 99tt 40%" << endl;
    cout << " 100 or morett 50%" << endl;
    cout << "----------------------------------" << endl;
    cout << "nn";
    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. nn";
    }


    system("pause");
    return 0;
}

最后一个else子句只在输入值为0时执行。下面是一个值超出

范围的输出示例
 This software package sells for $99. 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 $99.00 with a discount of 50% applied to the order.
The total cost of the sale is $2595186.00
Press any key to continue . . .

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

就像这里描述的:用户输入整数-错误处理,处理这个问题的一种方法是用一些错误处理代码包装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
}
但是,这不会处理整数溢出,因此完整的解决方案是使quantityint并使用
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;
}