分析std::string中的整数,但如果为float,则会失败 在C++和C中,有多种方法将字符串转换成整数,但是我没有发现在解析浮点数时失败的转换方法。 const float fnum = std::stof("1.5"); std::cout << fnum << std::endl; // prints "1.5", all okay const int inum = std::stoi("1.5"); std::cout << inum << std::endl; // prints "1", but wrong! const float fnum=std::stof(“1.5”); std::cout

分析std::string中的整数,但如果为float,则会失败 在C++和C中,有多种方法将字符串转换成整数,但是我没有发现在解析浮点数时失败的转换方法。 const float fnum = std::stof("1.5"); std::cout << fnum << std::endl; // prints "1.5", all okay const int inum = std::stoi("1.5"); std::cout << inum << std::endl; // prints "1", but wrong! const float fnum=std::stof(“1.5”); std::cout,c++,c++11,C++,C++11,对于包含十进制数的数字,您希望失败。您可以测试点,也可以测试十进制数字 if (num.find('.') != string::npos || num.find(',') != string::npos) cout << "Number is not integer" << endl; if(num.find(‘.)!=string::npos | | num.find(‘,’)!=string::npos) cout您可以使用boost词法转换。如果强制转换失

对于包含十进制数的数字,您希望失败。您可以测试点,也可以测试十进制数字

if (num.find('.') != string::npos || num.find(',') != string::npos)
   cout << "Number is not integer" << endl;
if(num.find(‘.)!=string::npos | | num.find(‘,’)!=string::npos)

cout您可以使用boost词法转换。如果强制转换失败,它将抛出异常

try
{
    number = boost::lexical_cast<int>(your_string);
}
catch (const boost::bad_lexical_cast& exec)
{
    // do something on fail
}
试试看
{
number=boost::词法转换(您的字符串);
}
捕获(const boost::bad\u词法\u cast&exec)
{
//失败时做某事
}

您应该反复检查数字是否解析为1)整数,2)浮点数,最后3)两者都不是。但是“解析”应该意味着整个字符串被使用

试着这样做:

#include <sstream>
#include <string>

bool TryAsInt(const std::string & s, long long int & out)
{
    std::istringstream iss(s);
    return (iss >> out >> std::ws) && (iss.get() == EOF);
}
然后,您仍然必须将其与检查所有字段的逻辑相结合

例如:

#include <cerrno>
#include <cstdlib>
#include <string>

bool TryAsInt(const std::string & s, long long int & out)
{
    char * e;
    errno = 0;

    out = std::strtoll(s.data(), &e, 0);
    return errno == 0 && s.data() + s.size() == e;
}
std::vector<string> raw_fields;

long long int n;
double x;

if (std::all_of(raw_fields.begin(), raw_fields.end(),
    [&n](const string & s) { return TryAsInt(s, n); })
{
    // integer case
}
else if (std::all_of(raw_fields.begin(), raw_fields.end(),
    [&x](const string & s) { return TryAsFloat(s, x); })
{
    // floating point case
}
else
{
    // just use raw_fields as-is
}
std::向量原始字段;
长整型n;
双x;
if(std::all_of(raw_fields.begin(),raw_fields.end(),
[&n](常量字符串&s){return TryAsInt(s,n);}
{
//整型
}
else if(std::all_of(raw_fields.begin()、raw_fields.end()),
[&x](常量字符串&s){return TryAsFloat(s,x);}
{
//浮点型
}
其他的
{
//只需按原样使用原始字段
}

如果需要更多类型检查,请查看boost。 例如,您可以执行以下操作:

#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <string>

template<typename T, typename RuleType>
bool is_type(std::string const& str, RuleType const& rule, T& val)
{
    using namespace boost::spirit::x3;

    auto beg = std::begin(str);
    auto end = std::end(str);

    auto ret = parse(beg,end, rule, val);
    return ret && (beg==end);
}

int main(int argc, char** argv)
{
    std::string s1="1.0";
    float v;
    std::cout << s1 << " is int ?   : " << is_type(s1, boost::spirit::x3::int_, v) << "\n";
    std::cout << s1 << " is float ? : " << is_type(s1, boost::spirit::x3::float_, v) << "\n";



    return 0;
}
#包括
#包括
#包括
模板
bool是_类型(std::string const&str、RuleType const&rule、T&val)
{
使用名称空间boost::spirit::x3;
自动beg=std::begin(str);
自动结束=标准::结束(str);
自动返回=解析(beg、end、rule、val);
返回ret&(beg==结束);
}
int main(int argc,字符**argv)
{
std::string s1=“1.0”;
浮动v;

std::cout对其使用普通std::stoi,但一定要检查字符串是否已完全使用。例如:

static bool isIntValue(const std::string& string, int32_t& intValue)
{
    try
    {
        size_t lastChar;
        intValue = std::stoi(string, &lastChar);
        return lastChar == string.size();
    }
    catch (...)
    {
        return false;
    }
}

此代码的执行速度比std::istringstream解决方案快得多。

还有另一个参数,可以像
strtol
的end参数一样使用。如果您觉得它“难看”那么搜索字符串以确定字符是否正确如何?@dommynik-您确定
const int fnum
?不是
const float fnum
?除了Joachim所说的之外,您还可以使用
stringstream
,并在转换调用后检查流是否为空。没有真正好的方法。无论哪种方法a)对于字符串解析。或b)使用boost的词法转换(这应该抛出异常,这有点难看)或者c)之后将其转换回字符串,看看字符串是否相同。啊,是的,stringstreams。@max66谢谢,抱歉,更改了!如果int是32位的,并且也是float,则float不能准确表示所有的int值。是的,我刚刚意识到float只能表示24位的整数。谢谢
不是唯一可以这样做的字符请使用浮点文本,但不要使用整数。您也需要排除
e
e
。谢谢,我会尝试一下-但我必须运行一些比较boost、stringstreams和stoi的计时基准。@dommynik:如果您需要性能,那么对输入执行原始词法分析会更有效。@r这比所有的冗余解析都要好。这不是很简单,但是可行。这些结果看起来很有希望,谢谢!
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <string>

template<typename T, typename RuleType>
bool is_type(std::string const& str, RuleType const& rule, T& val)
{
    using namespace boost::spirit::x3;

    auto beg = std::begin(str);
    auto end = std::end(str);

    auto ret = parse(beg,end, rule, val);
    return ret && (beg==end);
}

int main(int argc, char** argv)
{
    std::string s1="1.0";
    float v;
    std::cout << s1 << " is int ?   : " << is_type(s1, boost::spirit::x3::int_, v) << "\n";
    std::cout << s1 << " is float ? : " << is_type(s1, boost::spirit::x3::float_, v) << "\n";



    return 0;
}
static bool isIntValue(const std::string& string, int32_t& intValue)
{
    try
    {
        size_t lastChar;
        intValue = std::stoi(string, &lastChar);
        return lastChar == string.size();
    }
    catch (...)
    {
        return false;
    }
}