std::stringとstd::wstringの相互変換(utf限定)

  • 22
    Like
  • 5
    Comment
More than 1 year has passed since last update.

windows系のAPIを利用してC++を書いていると、やたらとwchar_t型の引数が要求されます。入力はただのASCII文字列だって時でもwchar_t型を要求されます。
でも入力したいのはファイルから読み込んだchar型の文字列だったり、std::stringで出力されるstd::exception.what()のメッセージだったり、、、
そんな時にはstd::stringからstd::wstringに変換しましょう。
std::wstring.c_str()を使えばwchar_t型も簡単に取得できます。
変換方法としてはstd::wsting_convertを利用します。
逆変換もできるのでついでにその方法も載せます。
対応はC++11〜

サンプルコード(内部コードにUTF8を利用する場合)


#include <iostream>
#include <locale> 
#include <codecvt> 
#include <cstdio>

int main(){
    std::string message = "ABCDEFG";
    std::wstring_convert<std::codecvt_utf8<wchar_t>,wchar_t> cv;
    //string→wstring
    std::wstring wsmessage = cv.from_bytes(message);
    std::wcout << wsmessage << std::endl;
    //wchar_t型を取得 
    wprintf("%S",wsmessage.c_str());

    //wstring→string
    std::string reconvert = cv.to_bytes(wsmessage);
    std::cout << reconvert << std::endl;
    return 0;
}

参考:http://www.cplusplus.com/reference/locale/wstring_convert/

2015/10/4 日本語利用の場合について追記しました

サンプルコード(日本語を利用する場合)

上のサンプルとほとんど変わりませんが、wcoutのlocaleを設定し直さないとうまく出力されないようです。


#include <iostream>
#include <locale> 
#include <codecvt> 

int main(){
    std::string message = u8"日本語バージョン";
    std::wstring_convert<std::codecvt_utf8<wchar_t>,wchar_t> cv;
    //string→wstring
    std::wstring wsmessage = cv.from_bytes(message);
    std::wcout.imbue(std::locale(""));
    std::wcout << wsmessage << std::endl;

    //wstring→string
    std::string reconvert = cv.to_bytes(wsmessage);
    std::cout << reconvert << std::endl;
    return 0;
}

また、いくつかやり方を試してみましたが、内部エンコーディングでsjis等utf以外の文字コードを使っている場合はwstring_convertを使ってもうまくいかないようです。
コメントで指摘されているように、mbsrtowcsを使ったほうがよさそうです。