c ++ WriteFile unicode字符
c++ WriteFile unicode characters
我正在尝试使用 WriteFile 函数将 wstring 写入 UTF-8 文件。
我希望文件包含这些字符“ÑÁ”,但我得到的是“�”。
这是代码
#include <iostream>
#include <cstdlib>
#include <sstream>
#include <string>
#include <fstream>
#include <windows.h>
#include <wchar.h>
#include <stdio.h>
#include <winbase.h>
using namespace std;
const char filepath [] = "unicode.txt";
int main ()
{
wstring str;
str.append(L"ÑÁ");
wchar_t* wfilepath;
// Create a file to work with Unicode and UTF-8
ofstream fs;
fs.open(filepath, ios::out|ios::binary);
unsigned char smarker[3];
smarker[0] = 0xEF;
smarker[1] = 0xBB;
smarker[2] = 0xBF;
fs << smarker;
fs.close();
//Open and write in the file with windows functions
mbstowcs(wfilepath, filepath, strlen(filepath));
HANDLE hfile;
hfile = CreateFileW(TEXT(wfilepath), GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
wstringbuf strBuf (str, ios_base::out|ios::app);
DWORD bytesWritten;
DWORD dwBytesToWrite = (DWORD) strBuf.in_avail();
WriteFile(hfile, &strBuf, dwBytesToWrite, &bytesWritten, NULL);
CloseHandle(hfile);
}
我使用这个命令行在 cygwin 上编译它:
g++ -std=c++11 -g Windows.C -o Windows
问题在这里:
wstringbuf strBuf (str, ios_base::out|ios::app);
WriteFile(hfile, &strBuf, dwBytesToWrite, &bytesWritten, NULL);
&strBuf
是 wstringbuf
对象的地址,它包含指向内容的指针、缓冲区位置和状态标志...而不是其内容所在的位置。
你可能想要
WriteFile(hfile, &str[0], /* etc */
但这只会存储您的 wstring
使用的相同编码。要以 UTF-8 编写,您可能需要使用 WideCharToMultiByte
(或 wcstombs
,因为您已经使用了 mbstowcs
)。
Ben 是正确的,您正在将原始 wchar_t
写入文件,而不是 UTF-8。
要编写 UTF-8,您可以考虑留在 C++ 中并执行以下操作:
std::locale loc (std::locale(), new std::codecvt_utf8<wchar_t>);
std::wofstream fs ("unicode.txt");
fs.imbue(loc);
fs << L"ÑÁ";
您需要先将 UTF-16 数据转换为 UTF-8,然后再将其写入文件。
而且不需要用 std::ofstream
创建文件,关闭它,然后用 CreateFileW()
重新打开它。只需打开文件一次并写入您需要的所有内容。
试试这个:
#include <iostream>
#include <cstdlib>
#include <string>
//#include <codecvt>
//#include <locale>
#include <windows.h>
#include <wchar.h>
#include <stdio.h>
using namespace std;
LPCWSTR filepath = L"unicode.txt";
string to_utf8(const wstring &s)
{
/*
wstring_convert<codecvt_utf8_utf16<wchar_t>> utf16conv;
return utf16conv.to_bytes(s);
*/
string utf8;
int len = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), s.length(), NULL, 0, NULL, NULL);
if (len > 0)
{
utf8.resize(len);
WideCharToMultiByte(CP_UTF8, 0, s.c_str(), s.length(), &utf8[0], len, NULL, NULL);
}
return utf8;
}
int main ()
{
wstring str = L"ÑÁ";
// Create a UTF-8 file and write in it using Windows functions
HANDLE hfile = CreateFileW(filepath, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hfile != INVALID_HANDLE_VALUE)
{
unsigned char smarker[3];
DWORD bytesWritten;
smarker[0] = 0xEF;
smarker[1] = 0xBB;
smarker[2] = 0xBF;
WriteFile(hfile, smarker, 3, &bytesWritten, NULL);
string strBuf = to_utf8(str);
WriteFile(hfile, strBuf.c_str(), strBuf.size(), &bytesWritten, NULL);
CloseHandle(hfile);
}
return 0;
}
我正在尝试使用 WriteFile 函数将 wstring 写入 UTF-8 文件。 我希望文件包含这些字符“ÑÁ”,但我得到的是“�”。
这是代码
#include <iostream>
#include <cstdlib>
#include <sstream>
#include <string>
#include <fstream>
#include <windows.h>
#include <wchar.h>
#include <stdio.h>
#include <winbase.h>
using namespace std;
const char filepath [] = "unicode.txt";
int main ()
{
wstring str;
str.append(L"ÑÁ");
wchar_t* wfilepath;
// Create a file to work with Unicode and UTF-8
ofstream fs;
fs.open(filepath, ios::out|ios::binary);
unsigned char smarker[3];
smarker[0] = 0xEF;
smarker[1] = 0xBB;
smarker[2] = 0xBF;
fs << smarker;
fs.close();
//Open and write in the file with windows functions
mbstowcs(wfilepath, filepath, strlen(filepath));
HANDLE hfile;
hfile = CreateFileW(TEXT(wfilepath), GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
wstringbuf strBuf (str, ios_base::out|ios::app);
DWORD bytesWritten;
DWORD dwBytesToWrite = (DWORD) strBuf.in_avail();
WriteFile(hfile, &strBuf, dwBytesToWrite, &bytesWritten, NULL);
CloseHandle(hfile);
}
我使用这个命令行在 cygwin 上编译它:
g++ -std=c++11 -g Windows.C -o Windows
问题在这里:
wstringbuf strBuf (str, ios_base::out|ios::app);
WriteFile(hfile, &strBuf, dwBytesToWrite, &bytesWritten, NULL);
&strBuf
是 wstringbuf
对象的地址,它包含指向内容的指针、缓冲区位置和状态标志...而不是其内容所在的位置。
你可能想要
WriteFile(hfile, &str[0], /* etc */
但这只会存储您的 wstring
使用的相同编码。要以 UTF-8 编写,您可能需要使用 WideCharToMultiByte
(或 wcstombs
,因为您已经使用了 mbstowcs
)。
Ben 是正确的,您正在将原始 wchar_t
写入文件,而不是 UTF-8。
要编写 UTF-8,您可以考虑留在 C++ 中并执行以下操作:
std::locale loc (std::locale(), new std::codecvt_utf8<wchar_t>);
std::wofstream fs ("unicode.txt");
fs.imbue(loc);
fs << L"ÑÁ";
您需要先将 UTF-16 数据转换为 UTF-8,然后再将其写入文件。
而且不需要用 std::ofstream
创建文件,关闭它,然后用 CreateFileW()
重新打开它。只需打开文件一次并写入您需要的所有内容。
试试这个:
#include <iostream>
#include <cstdlib>
#include <string>
//#include <codecvt>
//#include <locale>
#include <windows.h>
#include <wchar.h>
#include <stdio.h>
using namespace std;
LPCWSTR filepath = L"unicode.txt";
string to_utf8(const wstring &s)
{
/*
wstring_convert<codecvt_utf8_utf16<wchar_t>> utf16conv;
return utf16conv.to_bytes(s);
*/
string utf8;
int len = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), s.length(), NULL, 0, NULL, NULL);
if (len > 0)
{
utf8.resize(len);
WideCharToMultiByte(CP_UTF8, 0, s.c_str(), s.length(), &utf8[0], len, NULL, NULL);
}
return utf8;
}
int main ()
{
wstring str = L"ÑÁ";
// Create a UTF-8 file and write in it using Windows functions
HANDLE hfile = CreateFileW(filepath, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hfile != INVALID_HANDLE_VALUE)
{
unsigned char smarker[3];
DWORD bytesWritten;
smarker[0] = 0xEF;
smarker[1] = 0xBB;
smarker[2] = 0xBF;
WriteFile(hfile, smarker, 3, &bytesWritten, NULL);
string strBuf = to_utf8(str);
WriteFile(hfile, strBuf.c_str(), strBuf.size(), &bytesWritten, NULL);
CloseHandle(hfile);
}
return 0;
}