所以,我们有int32_t,int16_t,uint64_t等。但是在哪里atoi32,atoi16,atoui64等...? [英] So, we have int32_t, int16_t, uint64_t, etc.. But where are the atoi32, atoi16, atoui64, etc...?

查看:1240
本文介绍了所以,我们有int32_t,int16_t,uint64_t等。但是在哪里atoi32,atoi16,atoui64等...?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将表示数字的字符串输入转换为相应的数字类型。问题是我有严格的类型要求,例如,我不能接受 x> = 2 ^ 15 其中 int16_t



如何处理这种情况,无需从头开始编写所有转换函数?

p> PS



请不要建议 boost :: lexical_cast - 我已经使用它了。我正在说的功能将通过特定的模板特化来替换 lexical_cast 模板的默认实现,即:

 模板<> 
inline int32_t lexical_cast< int32_t,char const *>(const char * const& arg)
{
}
template<
inline int16_t lexical_cast< int16_t,char const *>(const char * const& arg)
{
}
...

理想情况下,最好拥有函数,例如 atoi32 atoi16 atoiu64 等...



/ strong>



我使用的是VS2010,所以没有运气< cinttypes> 。是的,有一个改进的 atoi 函数家族与 strtol具有相同的错误支持将是很好的



EDIT2



思考我值得发布我的解决方案:

  #pragma once 

#include< boost / lexical_cast.hpp>
#include< limits>

命名空间boost {

模板< class TInt,class conv>
TInt atoi(con​​v f,const char * arg)
{
char * stop;
TInt res = f(arg,& stop,10);
if(* stop)
{
throw_exception(bad_lexical_cast(typeid(TInt),typeid(const char *)));
}
return res;
}

template< class TInt>
typename std :: enable_if< std :: is_signed< TInt> :: value,TInt> :: type atoi(con​​st char * arg)
{
char * stop;
long res = strtol(arg,& stop,10)
if(* stop || std :: numeric_limits< TInt> :: min()> res || std :: numeric_limits< TInt> :: max()< res)
{
throw_exception(bad_lexical_cast(typeid(TInt),typeid(const char *)));
}
return(TInt)res;
}

template< class TInt>
typename std :: enable_if< std :: is_unsigned< TInt> :: value,TInt> :: type atoi(con​​st char * arg)
{
char * stop;
unsigned long res = strtoul(arg,& stop,10);
if(* stop || std :: numeric_limits< TInt> :: max()< res)
{
throw_exception(bad_lexical_cast(typeid(TInt),typeid(const char *) ));
}
return(TInt)res;
}

模板<> inline int8_t lexical_cast< int8_t,char const *>(const char * const& arg)
{
return atoi< int8_t>(arg)
}

模板<> inline uint8_t lexical_cast< uint8_t,char const *>(const char * const& arg)
{
return atoi< uint8_t>(arg)
}

模板<> inline int16_t lexical_cast< int16_t,char const *>(const char * const& arg)
{
return atoi< int16_t>(arg)
}

模板<> inline uint16_t lexical_cast< uint16_t,char const *>(const char * const& arg)
{
return atoi< uint16_t>(arg)
}

模板<> inline int32_t lexical_cast< int32_t,char const *>(const char * const& arg)
{
return atoi< int32_t>(strtol,arg)
}

模板<> inline uint32_t lexical_cast< uint32_t,char const *>(const char * const& arg)
{
return atoi< uint32_t>(strtoul,arg);
}

模板<> inline int64_t lexical_cast< int64_t,char const *>(const char * const& arg)
{
return atoi< int64_t>(_ strtoi64,arg)
}

模板<> inline uint64_t lexical_cast< uint64_t,char const *>(const char * const& arg)
{
return atoi< uint64_t>(_ strtoui64,arg);
}

模板<> inline double lexical_cast< double,char const *>(const char * const& arg)
{
char * stop;
double res = strtod(arg,& stop);
if(* stop)
{
throw_exception(bad_lexical_cast(typeid(double),typeid(const char *)));
}
return res;
}

模板<> inline float lexical_cast< float,char const *>(const char * const& arg)
{
char * stop;
double res = strtod(arg,& stop);
if(* stop || -FLT_MAX> res || FLT_MAX {
throw_exception(bad_lexical_cast(typeid(float),typeid(const char *)));
}
return res;
}

}

使用 strtol 系列函数。不幸的是,建议使用它的人也删除了他的帖子,我不知道为什么...

解决方案

函数实现所有必需的转换,< cinttypes> c $> cf> scanf 系列 / code>(在C ++ 11的组合C ++ 98编译器中,在C ++ 11中; < inttypes.h> )定义了适当的格式字符串说明符。例如,要从C字符串 s 中读取 int16_t ,请执行

  int16_t i; 
std :: sscanf(s,%SCNd16,& i);


I would like to convert a string input representing numbers to the respective numeric types. The problem is that I have strict type requirements, so, for instance, I cannot accept an x >= 2^15 where an int16_t value (signed) is expected.

How can I deal with this scenario, without writing all the conversion functions from scratch?

P.S.

Please, do not suggest boost::lexical_cast - I am using it already. The functions I am talking about are going to replace the default implementation of the lexical_cast template by means of the particular template specializations, namely:

template<>
inline int32_t lexical_cast<int32_t,char const *>(const char * const & arg)
{
}
template<>
inline int16_t lexical_cast<int16_t,char const *>(const char * const & arg)
{
}
...

Ideally, it would be nice to have functions, like atoi32, atoi16, atoiu64, etc...

EDIT

I am using VS2010, so no luck with <cinttypes>.

Yes, it would be nice to have an improved atoi family of functions having the same error support as strtol.

EDIT2

Thought it was worthwhile to post my solution:

#pragma once

#include <boost/lexical_cast.hpp>
#include <limits>

namespace boost {

template<class TInt, class conv>
TInt atoi(conv f, const char *arg)
{
  char* stop;
  TInt res = f(arg, &stop, 10);
  if (*stop)
  {
    throw_exception(bad_lexical_cast(typeid(TInt), typeid(const char *)));
  }
  return res;
}

template<class TInt>
typename std::enable_if<std::is_signed<TInt>::value, TInt>::type atoi(const char *arg)
{
  char* stop;
  long res = strtol(arg, &stop, 10);
  if (*stop || std::numeric_limits<TInt>::min() > res || std::numeric_limits<TInt>::max() < res)
  {
    throw_exception(bad_lexical_cast(typeid(TInt), typeid(const char *)));
  }
  return (TInt)res;
}

template<class TInt>
typename std::enable_if<std::is_unsigned<TInt>::value, TInt>::type atoi(const char *arg)
{
  char* stop;
  unsigned long res = strtoul(arg, &stop, 10);
  if (*stop || std::numeric_limits<TInt>::max() < res)
  {
    throw_exception(bad_lexical_cast(typeid(TInt), typeid(const char *)));
  }
  return (TInt)res;
}

template<> inline int8_t lexical_cast<int8_t,char const *>(const char * const & arg)
{
  return atoi<int8_t>(arg);
}

template<> inline uint8_t lexical_cast<uint8_t,char const *>(const char * const & arg)
{
  return atoi<uint8_t>(arg);
}

template<> inline int16_t lexical_cast<int16_t,char const *>(const char * const & arg)
{
  return atoi<int16_t>(arg);
}

template<> inline uint16_t lexical_cast<uint16_t,char const *>(const char * const & arg)
{
  return atoi<uint16_t>(arg);
}

template<> inline int32_t lexical_cast<int32_t,char const *>(const char * const & arg)
{
  return atoi<int32_t>(strtol, arg);
}

template<> inline uint32_t lexical_cast<uint32_t,char const *>(const char * const & arg)
{
  return atoi<uint32_t>(strtoul, arg);
}

template<> inline int64_t lexical_cast<int64_t,char const *>(const char * const & arg)
{
  return atoi<int64_t>(_strtoi64, arg);
}

template<> inline uint64_t lexical_cast<uint64_t,char const *>(const char * const & arg)
{
  return atoi<uint64_t>(_strtoui64, arg);
}

template<> inline double lexical_cast<double,char const *>(const char * const & arg)
{
  char* stop;
  double res = strtod(arg, &stop);
  if (*stop)
  {
    throw_exception(bad_lexical_cast(typeid(double), typeid(const char *)));
  }
  return res;
}

template<> inline float lexical_cast<float,char const *>(const char * const & arg)
{
  char* stop;
  double res = strtod(arg, &stop);
  if (*stop || -FLT_MAX > res || FLT_MAX < res)
  {
    throw_exception(bad_lexical_cast(typeid(float), typeid(const char *)));
  }
  return res;
}

}

So, in the end I am using the strtol family of functions. Unfortunately, the guy who has suggested to use them has also deleted his post, I wonder why...

解决方案

The scanf family of <cstdio> functions implements all the required conversions, and <cinttypes> (in C++11; <inttypes.h> in a combined C++98 compiler with C99 library) defines the appropriate format string specifiers. E.g., to read in an int16_t from the C string s, do

int16_t i;
std::sscanf(s, "%"SCNd16, &i);

这篇关于所以,我们有int32_t,int16_t,uint64_t等。但是在哪里atoi32,atoi16,atoui64等...?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆