如何检查输入是整数,字符串还是浮动在C 中

How to check whether an input is integer, string or float in C++

本文关键字:字符串 整数 何检查 检查 输入      更新时间:2023-10-16

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

例如。

如果输入是" Hello World"

输出应为:"输入是字符串"

如果输入为" 134"

输出应为:"输入是整数"

如果输入为" 133.23"

输出应为:"输入为float"

阅读字符串。

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

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

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

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

用户将始终输入一个字符串,您可以做的就是尝试将其转换为浮点,如果它成功了,那么它可能是float或int。如果浮点转换未成功,那么它可能没有数字。

#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的字符串表示?

如果您决定"如果可以将其解释为int,则是int。一个可以使用REGEXP进行操作,或进行一些格式检查。

由于所有INT可以转换为双打,并且双打的字符串表示形式可以转换为ints(也许还剩下一些垃圾),如果您关心差异,则可能需要检查是否有双重指标(可能在其中,可能是/-可能是/-的数字。P>

如果是int,则可以使用Regex ^ 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

我没有答案[编辑:我实际上是;请参阅一项旧式但没有例外的提案的结尾],但我无法将其适合评论 - 我担心"尝试使用stoi()&quot&quot"的建议:如果您不喜欢t有一个整数,然后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

#include <string>
#include <vector>
#include <tuple>
#include <iostream>
// compile and run with:                                                                                                                                              
// g++ -ggdb3 -O0 -Wall -Wextra -pedantic -Wno-unused-result str_has_number.cpp                                                                                       
// ./a.out                                                                                                                                                            
//                                                                                                                                                                    
// <2.5> -- 1                                                                                                                                                         
// <17> -- 1                                                                                                                                                          
// <dude> -- 0                                                                                                                                                        
// <2.5 junk> -- 0                                                                                                                                                    
// <stuff 12> -- 0                                                                                                                                                    
// <hey14.2> -- 0                                                                                                                                                     
// <55 3.14159> -- 0                                                                                                                                                  

using namespace std;
static bool dio_str_has_number(string s);
int main()
{
  vector<string> test_strings = {"2.5", "17", "dude", "2.5 junk",
                                 "stuff 12", "hey14.2", "55 3.14159"};
  for (string &s : test_strings) {
    bool has_num = str_has_number(s);
    cout << "<" + s + "> -- " << has_num << "n";
  }
}
/**                                                                                                                                                                   
 * @brief Find if the given string contains a number.                                                                                                                 
 */
static bool str_has_number(string s)
{
  char* p_end;
  // there are three different ways                                                                                                                                   
  (void) strtod(s.c_str(), &p_end);
  // std::ignore = strtod(s.c_str(), &p_end);                                                                                                                         
  // [[maybe_unused]] double x = strtod(s.c_str(), &p_end);                                                                                                           
  if (p_end != s.c_str() && p_end == s.c_str() + s.size()) {
    // if the end pointer is not at the start, and at it is at the end                                                                                                
    // end of the string, then we found a number                                                                                                                      
    return true;
  } else {
    return false;
  }
}

您可以轻松地将string.strof的CC_7或string.stroi用于try-Catch块中的CC_9:

#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;
    }
}