1 extern "C" {
2 #include <iconv.h>
3 }
4 #include <array>
5 #include <cstddef>
6 #include <cstdlib>
7 #include <iostream>
8 #include <string>
9 #include <system_error>
10 
11 class iconv_desc
12 {
13 private:
14   iconv_t iconvd_;
15 
16 public:
iconv_desc(const std::string & tocode,const std::string & fromcode)17   iconv_desc(const std::string& tocode, const std::string& fromcode)
18   {
19     iconvd_ = iconv_open(tocode.c_str(), fromcode.c_str());
20     if (iconvd_ == reinterpret_cast<iconv_t>(-1))
21       throw std::system_error(errno, std::system_category());
22   }
23 
~iconv_desc()24   ~iconv_desc() { iconv_close(iconvd_); }
25 
operator iconv_t()26   operator iconv_t() { return this->iconvd_; }
27 };
28 
main()29 int main()
30 {
31   try {
32     auto conv_d = iconv_desc{ "ISO-8859-1", "UTF-8" };
33     auto from_str = std::array<char, 10>{ u8"a\xC3\xA4o\xC3\xB6u\xC3\xBC" };
34     auto to_str = std::array<char, 7>{};
35 
36     auto from_str_ptr = from_str.data();
37     auto from_len = from_str.size();
38     auto to_str_ptr = to_str.data();
39     auto to_len = to_str.size();
40     const auto iconv_ret =
41       iconv(conv_d, &from_str_ptr, &from_len, &to_str_ptr, &to_len);
42     if (iconv_ret == static_cast<std::size_t>(-1))
43       throw std::system_error(errno, std::system_category());
44     std::cout << '\'' << from_str.data() << "\' converted to \'"
45               << to_str.data() << '\'' << std::endl;
46     return EXIT_SUCCESS;
47   } catch (const std::system_error& ex) {
48     std::cerr << "ERROR: " << ex.code() << '\n'
49               << ex.code().message() << std::endl;
50   }
51   return EXIT_FAILURE;
52 }
53