如何在 C++ 中检查输入是整数、字符串还是浮点数

问题描述 投票:0回答:6

我想知道的是,如果我要求用户输入一些内容,如果输入是整数、字符串或浮点值,我将如何输出。我想要一些方法来检查 C++14 中输入的数据类型。

例如。

如果输入是“Hello world”

输出应该是:“输入是字符串”

如果输入的是“134”

输出应该是:“输入是整数”

如果输入是“133.23”

输出应该是:“输入是浮点数”

c++ c++14
6个回答
10
投票

读取字符串。

<string>
中,标准库提供了一组函数,用于从字符串或 wstring 中的字符表示中提取数值。

使用

x=stoi(s,p)
。检查
p
- 如果读取整个字符串 - 它是整数。

使用

x=stof(s,p)
x=stod(s,p)
x=stold(s,p)
执行相同操作以检查 float/double/long double。

如果一切都失败 - 它是字符串。


6
投票

用户总是会输入一个字符串,你能做的就是尝试将其转换为浮点数,如果成功则可能是浮点数或整数。 如果浮点转换不成功,那么它可能不是一个数字。


5
投票
#include <iostream>
#include <string>
#include <boost/variant.hpp>
#include <sstream>


using myvariant = boost::variant<int, float, std::string>;

struct emit : boost::static_visitor<void>
{
    void operator()(int i) const {
        std::cout << "It's an int: " << i << '\n';
    }

    void operator()(float f) const {
        std::cout << "It's a float: " << f << '\n';
    }

    void operator()(std::string const& s) const {
        std::cout << "It's a string: " << s << '\n';
    }
};

auto parse(const std::string& s) -> myvariant
{
    char* p = nullptr;

    auto i = std::strtol(s.data(), &p, 10);
    if (p == s.data() + s.size())
        return int(i);

    auto f = std::strtof(s.data(), &p);
    if (p == s.data() + s.size())
        return f;


    return s;
}

void test(const std::string& s)
{
    auto val = parse(s);
    boost::apply_visitor(emit(), val);
}

int main()
{
    test("Hello world");
    test("134");
    test("133.23");
}

预期输出:

It's a string: Hello world
It's an int: 134
It's a float: 133.23

1
投票

输入是字符串。如果没有额外的协议,你怎么可能知道用户想要“1”是包含字符“1”的字符串还是整数 1 的字符串表示形式?

如果你决定“如果它可以被解释为 int,那么它就是 int。如果它可以是 double,那么它就是 double。否则它就是 string”,那么你可以进行一系列转换,直到一个有效,或者进行一些格式检查,也许使用正则表达式。

由于所有整数都可以转换为双精度数,并且双精度数的字符串表示形式也可以转换为整数(可能还剩下一些垃圾),如果您关心差异,您可能需要检查它是双精度数的指示符(带有也许是一个 .,可能是一个“e”,后面可能有 +/-。等等。您可以在互联网上找到正则表达式,具体取决于您想要允许的内容,前导 +、电子符号等。

如果是 int,则可以使用正则表达式 ^\d+$,否则如果是 double,则 [+-]?(?:0|[1-9]\d*)(?:.\d*)?( ?:[eE][+-]?\d+)?否则它是一个字符串。

这里有一些似乎有效的代码。 :)

#include <iostream>
#include <string>
#include <regex>
using namespace std;


void handleDouble(double d) {
    std::cout << "Double = " << d << "\n";
}

void handleInt(int i) {
    std::cout << "Int = " << i << "\n";
}

void handleString(std::string const & s) {
    std::cout << "String = " << s << "\n";
}

void parse(std::string const& input) {
    static const std::regex doubleRegex{ R"([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)" };
    static const std::regex intRegex{ R"(\d+)"};

    if (std::regex_match(input, intRegex)){
        istringstream inputStream(input);
        int i;
        inputStream >> i;
        handleInt(i);
    }
    else if (std::regex_match(input, doubleRegex)) {
        istringstream inputStream(input);
        double d;
        inputStream >> d;
        handleDouble(d);
    }
    else {
        handleString(input);
    }
}

int main()
{
    parse("+4.234e10");
    parse("1");
    parse("1.0");
    parse("123abc");
}

输出:

Double = 4.234e+10
Int = 1
Double = 1
String = 123abc

0
投票

您可以轻松地将

string.strof
换成
float
string.stroi
换成
int
在 try-catch 块中:

#include <string>
bool isFloat(string str) {
    try {
        float floatCheck = stof(str);
        return true;
    }
    catch (...) {
        return false;
    }
}

bool isInt(string str) {
    try {
        int intCheck = stoi(str);
        return true;
    }
    catch (...) {
        return false;
    }
}

0
投票

我没有答案,但我无法将其放入评论中 - 我担心涉及“尝试使用 stoi()”的建议:如果你没有整数,那么 stoi() 会抛出一个例外。突然间,您进入了异常处理领域,这种逻辑方法有问题(您不想将异常处理用作逻辑),并且可能会显着减慢速度。请参阅下面的代码以了解如何触发异常。

在我看来,基于解析文本的解决方案更合适。

#include <string>  
#include <iostream>  

// compile and run with:
// g++ -Wall test_stoi.cpp
// ./a.out
// output should look like:
// terminate called after throwing an instance of 'std::invalid_argument'
// what():  stoi


using namespace std;

int main()
{
  string s = "dude";
  size_t pos;
  int x = stoi(s, &pos);
  cout << "x,pos: " << x << "   " << pos << "\n";
}

脚注:C++“官方”常见问题解答明确指出:

不要使用异常作为从函数返回值的另一种简单方式。大多数用户假设——正如语言定义所鼓励的那样——**异常处理代码是错误处理代码**,并且实现被优化以反映该假设。

https://isocpp.org/wiki/faq/exceptions

© www.soinside.com 2019 - 2024. All rights reserved.