因此,我们有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...?

本文关键字:但是 atoi32 atoui64 atoi16 在哪里 int16 我们有 int32 因此 uint64      更新时间:2023-10-16

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

在不从头开始编写所有转换函数的情况下,我如何处理这种情况?

p.S.

请不要建议boost::lexical_cast-我已经在使用它了。我所说的函数将通过特定的模板专业化来取代lexical_cast模板的默认实现,即:

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)
{
}
...

理想情况下,最好有atoi32atoi16atoiu64等功能。

编辑

我使用的是VS2010,所以<cinttypes>运气不好。

是的,如果有一个改进的atoi函数族,具有与strtol相同的错误支持,那就太好了。

EDIT2

我觉得发布我的解决方案是值得的:

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

所以,最后我使用的是strtol函数族。不幸的是,建议使用它们的人也删除了他的帖子,我想知道为什么。。。

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

int16_t i;
std::sscanf(s, "%"SCNd16, &i);
相关文章: