arc_lupus
arc_lupus

Reputation: 4114

Determine buffer size for __i64toa_s

I want to convert some numbers from __int64 to char. For this purpose I want to use the function __i64toa_s, as suggested by MS. The function expects a char buffer for the return value. How can I determine the minimal needed size of this buffer? I don't want to get errors because of a too small buffer, but I don't want to waste space, too.
Thank you!

Upvotes: 0

Views: 596

Answers (3)

klaus triendl
klaus triendl

Reputation: 1359

I would suggest a more generic meta-function, which I use myself whenever I'm in need.

It calculates the maximum storage size for any numerical integral type in radix 10 by facilitating std::numeric_limits<>:

/** @short Metafunction that calculates the maximum storage size for a string
 *  representation of a numerical type in base10, eventually including the sign.
 *
 *  @tparam T integral type, forwarded to std::numeric_limits<>
 *  @tparam null_inclusive whether to include the terminating null-character
 *  into the storage size
 */
template<typename T, bool null_inclusive = true>
struct digits10_storage_size:
  std::integral_constant<
    std::size_t,
    // note: digits10 returns the number of deciaml digits that the type can
    // represent without loss of precision, i.e. for char we get 2 digits (0..99)
    //
    // so we add here 1 to get 3 digits because [100..255] are 3 digits.
    // we add another time 1 because of an eventual sign (+/-) that a conversion
    // function could produce, plus finally the trailing \0-character eventually
    std::numeric_limits<T>::digits10 + 2 + null_inclusive
  >
{};

Advantages I see:

  • compile-time solution
  • fixed buffer that exactly fits the type instead of guessing, no matter the compiler/platform
  • by using meta-programming techniques one could even generalize this meta-function for different radices

Usage:

char szNum[digits10_storage_size<__int64>::value];
_i64toa_s(i, szNum, 10);
// ... or use "unsafe" version because of correctly precomputed buffer:
_i64toa(i, szNum, 10);

Upvotes: 1

David Heffernan
David Heffernan

Reputation: 612794

Assuming decimal output, you need a buffer of at least 21 characters. You need to allow for 19 digits for a 64 bit integer represented as decimal, a minus sign, and a null terminator.

However, since you are using C++, it would seem to me to make much more sense to use a C++ solution and avoid null-terminated C strings. I see no reason to use __i64toa_s. Use a string stream instead.

Upvotes: 1

ForEveR
ForEveR

Reputation: 55887

You can simply count, how many digits is in __int64 value. By loop, or by log10(value) + 1, if log10 is overloaded for __int64.

Upvotes: 2

Related Questions