Code:
#include <SDKDDKVer.h>
#include <Windows.h>
#include <sstream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iostream>
#include <fcntl.h>
#include <io.h>
//------------------------------------------------------------------------------
// NOTE - This source file must be saved as Unicode with BOM!
const wchar_t UTF16_MSG[] = L"绽湛栈蘸菚颤张章彰璋漳樟蟑鄣獐嫜餦麞粻鏱蔁騿掌鐣仉鞝涨障丈帐仗";
//------------------------------------------------------------------------------
bool read_utf8_file(const char *pathname,
std::wstring &contents,
bool b_rn2n = true) // convert "\r\n"->"\n"
{
std::ifstream fin(pathname, std::ios::binary);
if (!fin)
return false;
BYTE bom[4];
bool bUTF8BOM = false;
if (!fin.read((char*)bom, 4))
{
// if we hit eof then file is less than 4 bytes
if (!fin.eof())
return false;
fin.clear();
}//if
else
{
bUTF8BOM = (bom[0] == 0xEF) && (bom[1] == 0xBB) && (bom[2] == 0xBF);
// TODO - check for non-UTF8 BOM's
// UTF8 BOM is 3 bytes, go back 1 byte if needed
if (bUTF8BOM)
fin.seekg(-1, std::ios::cur);
}//else
if (!bUTF8BOM)
fin.seekg(0, std::ios::beg); // setup to re-read first 3 bytes
std::stringstream ss;
if (!(ss << fin.rdbuf())) // note: will fail if file is empty
return false;
fin.close(); // release resources
const std::string &utf8 = ss.str();
ss.str(""); // release resources
// NOTE: we are assuming that the number of bytes in a UTF8 string is
// always >= to the number of wchar_t's required to represent that
// string in UTF16LE - which should hold true
size_t len = utf8.length();
std::vector<wchar_t> wbuff(len);
int wlen = MultiByteToWideChar(CP_UTF8, 0,
utf8.c_str(), len,
&wbuff[0], len);
if (!wlen)
return false;
wbuff.resize(wlen); // wlen may be < len
if (b_rn2n)
contents.assign(wbuff.begin(),
std::remove(wbuff.begin(), wbuff.end(), '\r'));
else
contents.assign(wbuff.begin(), wbuff.end());
return true;
}//read_utf8_file
//------------------------------------------------------------------------------
std::wstring str_to_wstr(const std::string &str, UINT cp = CP_ACP)
{
int len = MultiByteToWideChar(cp, 0, str.c_str(), str.length(), 0, 0);
if (!len)
return L"ErrorA2W";
std::vector<wchar_t> wbuff(len + 1);
// NOTE: this does not NULL terminate the string in wbuff, but this is ok
// since it was zero-initialized in the vector constructor
if (!MultiByteToWideChar(cp, 0, str.c_str(), str.length(), &wbuff[0], len))
return L"ErrorA2W";
return &wbuff[0];
}//str_to_wstr
//------------------------------------------------------------------------------
std::string wstr_to_str(const std::wstring &wstr, UINT cp = CP_ACP)
{
int len = WideCharToMultiByte(cp, 0, wstr.c_str(), wstr.length(),
0, 0, 0, 0);
if (!len)
return "ErrorW2A";
std::vector<char> abuff(len + 1);
// NOTE: this does not NULL terminate the string in abuff, but this is ok
// since it was zero-initialized in the vector constructor
if (!WideCharToMultiByte(cp, 0, wstr.c_str(), wstr.length(),
&abuff[0], len, 0, 0))
{
return "ErrorW2A";
}//if
return &abuff[0];
}//wstr_to_str
//------------------------------------------------------------------------------
using namespace std;
int main()
{
_setmode(_fileno(stdout), _O_U16TEXT);
_setmode(_fileno(stdin), _O_U16TEXT);
ofstream fout("file_out.txt", ios::binary | ios::out);
if (!fout)
return 1;
// write the UTF8 BOM
if (!fout.write("\xEF\xBB\xBF", 3))
return 1;
// convert our message to UTF8
string utf8_msg = wstr_to_str(UTF16_MSG, CP_UTF8);
if (!fout.write(utf8_msg.c_str(), utf8_msg.length()))
return 1;
fout.close();
wstring file_msg;
if (!read_utf8_file("file_out.txt", file_msg))
return 1;
wcout << file_msg << endl;
wcout << L"Enter Msg:";
wstring con_msg;
getline(wcin, con_msg);
wcout << L"You entered: " << con_msg << endl;
return 0;
}//main
Output: