当输入预期为整数时如何检测浮点数?

How to detect floats when input is expected to be integer?

如何检测输入了浮点数?

我写了一个程序如下。 当输入季度数的值时,例如 5。 输出为 5。这是预期的。

当我输入5.5 输出为 5。这是不正确的,因为不可能得到四分之一的 0.5。

这是在 C++ 中解释值的方式的问题吗?我如何检测到该数字是浮点数而不是整数?

int calculation()
{
   int quarters = 0;
   cout << "Number of quarters:";
   cin >> quarters;

   cout << "the number of quarters you have: " << quarters;
} 

完全实施

int calculation()
{
    float total;

    int quarters = 0;
    int nickels = 0;
    int dimes = 0;
    int pennies = 0;

    std::string input_quarters;
    std::string input_nickels;
    std::string input_dimes;
    std::string input_pennies;

    // reading to a string will read to end of line
    //quarters
    std::cout << "Number of quarters: ";
    std::cin >> input_quarters;

    std::cout << "Number of nickels: ";
    std::cin >> input_nickels;

    std::cout << "Number of Dimes: ";
    std::cin >> input_dimes;

    std::cout << "Number of pennies: ";
    std::cin >> input_pennies;

    // Allow 1 or more characters in range '0'-'9' until end of string
    std::regex numbers_only("[0-9]+$");

    // check if input matches pattern
    if (std::regex_match(input_quarters, numbers_only) && std::regex_match(input_nickels, numbers_only) && std::regex_match(input_dimes, numbers_only) && std::regex_match(input_pennies, numbers_only))
    {
        // convert string to int explicitly
        quarters = std::stoi(input_quarters);
        std::cout << "quarters now = " << quarters;
        total = quarters / 4 + (fmod(quarters, 4) * 0.25);

        nickels = std::stoi(input_nickels);
        std::cout << "Nickels now = " << nickels;
        total = total + nickels / 20 + (fmod(nickels, 20) * 0.05);

        dimes = std::stoi(input_dimes);
        std::cout << "Dimes now = " << dimes;
        total = total + dimes / 10 + fmod(dimes, 10) * 0.1;

        pennies = std::stoi(input_pennies);
        std::cout << "pennies now = " << pennies;
        total = total + pennies / 100 + fmod(pennies, 20) * 0.01;

        std::cout << "Total $ = " << total;
    }

    else
    {
        std::cout << "input was not a whole number";
    }

    return total;
}

这个程序展示了首先发生的事情(正如 Galik 提到的阅读停止在 。) 然后它显示了如何在将其转换为 int 之前检查您的完整输入。

#include <iostream>
#include <string>
#include <regex>

int main()
{
    // ----------------------------------------------------------------
    // piece of code showing what happens in the orignal code

    int quarters = 0;
    std::string input;

    std::cout << "Number of quarters (enter 5.5 here) : ";
    std::cin >> quarters;

    std::cout << std::endl << "remaining input : ";
    std::cin >> input;
    std::cout << "'" << input << "' ";

    std::cout << "the number of quarters you have: " << quarters << std::endl << std::endl;

    // reading to a string will read to end of line
    std::cout << "Number of quarters (with input checking) : ";
    std::cin >> input;
    std::cout << "Your full input = " << input << std::endl;

    
    // ----------------------------------------------------------------
    // piece of code with input checking

    std::regex numbers_only("[0-9]+$"); // Allow 1 or more characters in range '0'-'9' until end of string

    // check if input matches pattern
    if (std::regex_match(input, numbers_only))
    {
        //https://en.cppreference.com/w/cpp/string/basic_string/stol
        // convert string to int explicitly
        quarters = std::stoi(input);
        std::cout << "quarters now = " << quarters;
    }
    else
    {
        std::cout << "input was not a whole number" << std::endl;
    }

    return 0;
}

解决该问题的一种方法是从用户那里检索字符串并尝试使用 std::stoi.

对其进行转换
std::string str;
std::cin >> str;
std::size_t pos{0};
int val = std::stoi(str, &pos);

如果pos不等于str.size(),则意味着一些字符被丢弃,因此用户可能没有给出正确的整数值。

此处示例: https://godbolt.org/z/cvPKcsTx4

#include <iostream>
#include <regex>
#include <string>
#include <cmath>

bool is_valid_coin_amount(const std::string& input)
{
    // Allow 1 or more characters in range '0'-'9' until end of string
    // only initialize regex once by making it static (optimization)
    static std::regex numbers_only("[0-9]+$");
    return std::regex_match(input, numbers_only);
}

auto input_amount(const std::string& coin_type)
{
    std::string input;

    while (true)
    {
        std::cout << "Enter number of " << coin_type << " : ";
        std::cin >> input;

        if (!is_valid_coin_amount(input))
        {
            std::cout << std::endl << "Input is not a valid amount, " << std::endl;
        }
        else
        {
            break;
        }
    }

    return std::stoul(input); // amount is always positive so use unsigned type
}

double convert(int value, int scale)
{
    auto v = static_cast<double>(value);
    auto s = static_cast<double>(scale);
    return (v / scale) + (std::fmod(v, scale) / scale);
}


double calculate_total()
{
    double total{ 0.0 };

    int quarters = input_amount("quarters");
    int nickels = input_amount("nickels");
    int dimes = input_amount("dimes");
    int pennies = input_amount("pennies");

    std::cout << "quarters = " << quarters << std::endl;
    total += convert(quarters, 4);

    std::cout << "Nickels = " << nickels << std::endl;
    total += convert(nickels, 20);

    std::cout << "Dimes = " << dimes << std::endl;
    total += convert(dimes, 10);

    std::cout << "Pennies = " << pennies << std::endl;
    total += convert(pennies, 100);
    //total = total + pennies / 100 + fmod(pennies, 20) * 0.01f; <<== is the 20 here correct? if so convert must be modified a bit

    std::cout << "Total $ = " << total;

    return total;
}

int main()
{
    auto total = calculate_total();
    return 0;
}