to_stringとto_wstringがない環境にむけて、自分で書いてみました。sprintf系関数で文字列にすれば良いので、そう難しくはありません。

なお、Visual C++を念頭に置いて書いたので、以下を仮定しています。

  • 文字列への変換にsprintf_sおよびswprintf_sを使用。
  • 文字数の取得に_scprintfおよび_scwprintfを使用。
  • std::stringおよびstd::wstringの内部バッファがメモリ上連続していること(C++11非対応でも)。
  • doubleとlong doubleの内部表現が同じ。
  • intとlongの内部表現が同じ。
  • unsignedとunsigned longの内部表現が同じ。
#include <string>
#include <stdio.h>
 
std::string to_string(long double x)
{
  std::string result;
  result.resize(_scprintf("%Lf", x) + 1);
  int length = sprintf_s(&result[0], result.size(), "%Lf", x);
  if (length < 0)
  {
    throw std::runtime_error("to_string");
  }
  result.resize(static_cast<std::size_t>(length));
  return result;
}
 
std::string to_string(double x)
{
  return to_string(static_cast<long double>(x));
}
 
std::string to_string(float x)
{
  return to_string(static_cast<long double>(x));
}
 
std::string to_string(unsigned long long x)
{
  std::string result;
  result.resize(21); // strlen("-9223372036854775808") + 1;
  int length = sprintf_s(&result[0], result.size(), "%llu", x);
  if (length < 0)
  {
    throw std::runtime_error("to_string");
  }
  result.resize(static_cast<std::size_t>(length));
  return result;
}
 
std::string to_string(long long x)
{
  std::string result;
  result.resize(21); // strlen("-9223372036854775808") + 1;
  int length = sprintf_s(&result[0], result.size(), "%lld", x);
  if (length < 0)
  {
    throw std::runtime_error("to_string");
  }
  result.resize(static_cast<std::size_t>(length));
  return result;
}
 
std::string to_string(unsigned long x)
{
  std::string result;
  result.resize(11); // strlen("4294967295") + 1;
  int length = sprintf_s(&result[0], result.size(), "%lu", x);
  if (length < 0)
  {
    throw std::runtime_error("to_string");
  }
  result.resize(static_cast<std::size_t>(length));
  return result;
}
 
std::string to_string(long x)
{
  std::string result;
  result.resize(12); // strlen("-2147483648") + 1;
  int length = sprintf_s(&result[0], result.size(), "%ld", x);
  if (length < 0)
  {
    throw std::runtime_error("to_string");
  }
  result.resize(static_cast<std::size_t>(length));
  return result;
}
 
std::string to_string(unsigned x)
{
  return to_string(static_cast<unsigned long>(x));
}
 
std::string to_string(int x)
{
  return to_string(static_cast<long>(x));
}
 
std::wstring to_wstring(long double x)
{
  std::wstring result;
  result.resize(_scwprintf(L"%Lf", x) + 1);
  int length = swprintf_s(&result[0], result.size(), L"%Lf", x);
  if (length < 0)
  {
    throw std::runtime_error("to_wstring");
  }
  result.resize(static_cast<std::size_t>(length));
  return result;
}
 
std::wstring to_wstring(double x)
{
  return to_wstring(static_cast<long double>(x));
}
 
std::wstring to_wstring(float x)
{
  return to_wstring(static_cast<long double>(x));
}
 
std::wstring to_wstring(unsigned long long x)
{
  std::wstring result;
  result.resize(21); // strlen("-9223372036854775808") + 1;
  int length = swprintf_s(&result[0], result.size(), L"%llu", x);
  if (length < 0)
  {
    throw std::runtime_error("to_wstring");
  }
  result.resize(static_cast<std::size_t>(length));
  return result;
}
 
std::wstring to_wstring(long long x)
{
  std::wstring result;
  result.resize(21); // strlen("-9223372036854775808") + 1;
  int length = swprintf_s(&result[0], result.size(), L"%lld", x);
  if (length < 0)
  {
    throw std::runtime_error("to_wstring");
  }
  result.resize(static_cast<std::size_t>(length));
  return result;
}
 
std::wstring to_wstring(unsigned long x)
{
  std::wstring result;
  result.resize(11); // strlen("4294967295") + 1;
  int length = swprintf_s(&result[0], result.size(), L"%lu", x);
  if (length < 0)
  {
    throw std::runtime_error("to_wstring");
  }
  result.resize(static_cast<std::size_t>(length));
  return result;
}
 
std::wstring to_wstring(long x)
{
  std::wstring result;
  result.resize(12); // strlen("-2147483648") + 1;
  int length = swprintf_s(&result[0], result.size(), L"%ld", x);
  if (length < 0)
  {
    throw std::runtime_error("to_wstring");
  }
  result.resize(static_cast<std::size_t>(length));
  return result;
}
 
std::wstring to_wstring(unsigned x)
{
  return to_wstring(static_cast<unsigned long>(x));
}
 
std::wstring to_wstring(int x)
{
  return to_wstring(static_cast<long>(x));
}
 
#include <iostream>
#include <climits>
#include <cfloat>
 
int main()
{
  // 一般的にstd::coutとstd::wcoutの混在はNGだが、
  // Visual C++は期待通り動くので。
  std::cout << to_string(INT_MIN) << std::endl;
  std::cout << to_string(UINT_MAX) << std::endl;
  std::cout << to_string(LLONG_MIN) << std::endl;
  std::cout << to_string(ULLONG_MAX) << std::endl;
  std::cout << to_string(DBL_MAX) << std::endl;
  std::wcout << to_wstring(INT_MIN) << std::endl;
  std::wcout << to_wstring(UINT_MAX) << std::endl;
  std::wcout << to_wstring(LLONG_MIN) << std::endl;
  std::wcout << to_wstring(ULLONG_MAX) << std::endl;
  std::wcout << to_wstring(DBL_MAX) << std::endl;
}

次は、stoi系関数ですかね。


スポンサード リンク

この記事のカテゴリ

  • ⇒ to_stringとto_wstringを作ってみる
  • ⇒ to_stringとto_wstringを作ってみる