So we have int32_t, int16_t, uint64_t, etc. But where is atoi32, atoi16, atoui64, etc. ??

I would like to convert string input representing numbers to the corresponding number types. The problem is that I have strict type requirements, so, for example, I cannot accept x> = 2 ^ 15 , where the value int16_t (signature) is expected.

How can I handle this scenario without writing all the conversion functions from scratch?

PS

Please do not offer boost::lexical_cast - I am using it already. The functions I'm talking about are going to replace the standard implementation of the lexical_cast template with the help of special specialized templates, 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 features 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 feature family with the same bug support as strtol .

EDIT2

Thought it was worth publishing 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 use the strtol family of functions. Unfortunately, the guy who suggested using them also deleted his post, I wonder why ...

+4
source share
1 answer

The <cstdio> scanf family of functions implements all the necessary transformations, and <cinttypes> (in C ++ 11; <inttypes.h> in the combined C ++ 98 compiler with the C99 library) defines the corresponding format string with specifiers. For example, to read in int16_t from the string C s , do

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

Source: https://habr.com/ru/post/1392537/


All Articles