イネマルのプログラミング備忘録

趣味プログラマーのメモ

string wstring 相互変換 (Windows用)

stringとwstringの相互変換

stlを使用していると、文字列にstd::stringを使用する事が多いですが、
std::wstringに変換したいタイミングがあるかもしれません。
そんな時の対応方法の一例です。

注意

Windows環境で使える変換手法を覚書きします。
今回は
「MultiByteToWideChar/WideCharToMultiByte」
を使用した例です。
マルチプラットフォームな方法では、

  • C++11の「std::wsting_convert」
  • C/C++の「mbsrtowcs/std::mbsrtowcs」

があるらしいです。

確認用のプログラム

stringとwstringの文字列を
それぞれwstringとstringに変換してコンソールに表示してみる。

※動作確認は、VC2013で行いました

StringConverter.hpp

// StringConverter.hpp
#pragma once

#include <string>
#include <vector>
#include <locale>
#include <winstring.h>

namespace StringConverter
{
	// コードページ定義
	enum CodePageID : unsigned int
	{
		ANSI	= CP_ACP,	// ANSI
		OEM		= CP_OEMCP,	// OEM(依存)
		MAC		= CP_MACCP,	// MAC
		UTF7	= CP_UTF7,	// UTF-7
		UTF8	= CP_UTF8	// UTF-8
	};

	// ロケール設定
	static void SetGlobalLocale(const std::string localeName = "")
	{
		std::locale::global(std::locale(localeName));
		setlocale(LC_ALL, std::locale().c_str());
	}

	// string から wstring 変換
	static std::wstring StringToWString(const std::string& refSrc, unsigned int codePage = CodePageID::ANSI)
	{
		std::vector<wchar_t> buffer(MultiByteToWideChar(codePage, 0, refSrc.c_str(), -1, nullptr, 0));
		MultiByteToWideChar(codePage, 0, refSrc.c_str(), -1, &buffer.front(), buffer.size());
		return std::wstring(buffer.begin(), buffer.end());
	}

	// wstring から string 変換
	static std::string WStringToString(const std::wstring& refSrc, unsigned int codePage = CodePageID::OEM)
	{
		std::vector<char> buffer(WideCharToMultiByte(codePage, 0, refSrc.c_str(), -1, nullptr, 0, nullptr, nullptr));
		WideCharToMultiByte(codePage, 0, refSrc.c_str(), -1, &buffer.front(), buffer.size(), nullptr, nullptr);
		return std::string(buffer.begin(), buffer.end());
	}
}

main.cpp

// main.cpp
#include <iostream>
#include <string>
#include "StringConverter.hpp"

int main()
{
	using namespace std;

	// 適当に文字用意
	std::string msgA = "ABCアイウエオ@日本語";
	std::wstring msgW = L"ABCアイウエオ@日本語";

	// ロケール設定
	StringConverter::SetGlobalLocale();

	// 表示
	cout << StringConverter::WStringToString(msgW) << endl;
	wcout << StringConverter::StringToWString(msgA) << endl;

	// 入力待ち
	rewind(stdin), getchar();
	return 0;
}

あとがき

関数の引数が対応していなくてやむなく変換ってパターンもあるけど
本来は、関数側が対応するべきだと思う。
Win32APIは大体、
(関数名)Aと(関数名)Wを用意しているから問題は起こりにくいと思うけど、
外部ライブラリが何故かwchar_tしか対応してない状況があって変換方法を備忘録行き。