How to convert u32string to int in C++11?
Asked Answered
K

3

8

How can we convert u32string to int in C++11?

Additional, what method should I use to convert part of such string to int - lets say having begin and end iterator available?

I've tried:

u32string test=U"14";
cout << atoi(test.c_str());

but it throws:

candidate function not viable: no known conversion from 'const char32_t *' to 'const char *' for 1st argument
extern int atoi (__const char *__nptr)
Kimberliekimberlin answered 16/5, 2013 at 17:27 Comment(0)
A
10
#include <locale>   // wstring_convert
#include <codecvt>  // codecvt_utf8
#include <iostream> // cout
#include <string>   // stoi and u32string

int main() {
  std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;

  std::u32string str = U"14";
  std::cout << std::stoi(convert.to_bytes(str));
}

This depends on UTF-8 and the "C" locale using the same representation for digits.


GCC's standard library implementation libstdc++ does not include the codecvt header or std::wstring_convert yet. libc++ does include both of these, as does Visual Studio's standard library implementation. If you have to use libstdc++ you may find it easiest to just implement a simple conversion function yourself.

#include <algorithm> // transform
#include <iterator>  // begin, end, and back_inserter

std::string u32_to_ascii(std::u32string const &s) {
  std::string out;
  std::transform(begin(s), end(s), back_inserter(out), [](char32_t c) {
    return c < 128 ? static_cast<char>(c) : '?';
  });
  return out;
}

int u32toi(std::u32string const &s) { return stoi(u32_to_ascii(s)); }
Animism answered 16/5, 2013 at 18:1 Comment(4)
it seems that codecvt is not yet implemented for clang and gcc ... How can I solve this problem in such situation?Kimberliekimberlin
@danilo2 If you look at e.g. this reference you see that the std::codecvt_utf8 is a specialization of std::codecvt. If you don't have std::codecvt_utf8 then you can simply do e.g. typedef std::codecvt<char32_t, char, std::mbstate_t> utf8_codecvt_t;Tuneberg
While compiling the code with gcc-4.7.2 or clang-3.4 there is no file codecv so it could not even be included ... so it is impossible to solve it that way, am I wrong?Kimberliekimberlin
@danilo2 First of all try to use the -std=c++11 flag when building, otherwise the <codecvt> is new in C++11, the codecvt class is defined in the header file <locale>.Tuneberg
T
0

Edited because my first answer was stupid.

Here is what i managed to do, however its probably not very efficient, and it assumes your string is valid.

#include <string>
#include <iostream>

int     main()
{
  std::u32string str = U"14";

  std::string res;
  for (auto c = str.begin(); c != str.end(); ++c)
    {
      char t = *c;
      res.push_back(t);
    }
  std::cout << "\nVal = " << atoi(res.c_str()) << std::endl;
  return (0);
}
Treadway answered 16/5, 2013 at 17:30 Comment(3)
No: no known conversion from 'const char32_t *' to 'const char *' for 1st argumentKimberliekimberlin
Works for u16string and u32string, Windows MinGW-w64 4.9.0Freemason
This answer is completely wrong! You can't convert char32_t to char. generally you need a separate function for converting from u32string to string. Then you have to print it.Barthelemy
S
0

There is no standard library function for this, but thankfully it's quite easy to implement.

Here's an example of how to do it in a generic way and without costly conversions to std::string.

#include <string>
#include <iostream>

template<typename Out, typename In>
Out parse_int(In const& in)
{
    Out res = 0;
    std::size_t start = 0;
    while (std::isspace(in[start])) {
        start++;
    }
    std::size_t i = start;
    if (in[i] == '-') {
        i++;
    }
    while (std::isdigit(in[i])) {
        res = res * 10 + in[i++] - '0';
    }

    return in[start] == '-' ? -res : res;
}

int main()
{
    std::u32string s{ '1','2','3','4','5' };

    std::cout << parse_int<long long>(s) << std::endl;
}

The parse_int function works with u16string, u32string, u8string, string and wstring, exploiting the fact that digits are represented using the same values in all character types.

Live demo

Selectivity answered 1/12, 2022 at 20:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.