Я нашел ответ здесь . По сути, это не изменило мою оболочку входа обратно в bash.
Я подозреваю, что sizeof (wchar_t) 4 в Вашей среде - т.е. это выписывает UTF-32/UCS-4 вместо UTF-16. Это, конечно, на что похож шестнадцатеричный дамп.
Это достаточно легко протестировать (просто распечатывают sizeof (wchar_t)), но я вполне уверен, это - то, что продолжается.
Для движения от UTF-32 wstring к UTF-16, необходимо будет применить надлежащее кодирование, поскольку суррогатные пары играют роль.
Необходимо посмотреть на выходной файл в Hex-редакторе, таком как WinHex, таким образом, Вы видите фактические биты и байты, чтобы проверить, что выводом является на самом деле UTF-16. Отправьте его здесь и сообщите нам результат. Это скажет нам, обвинить ли Firefox или Вашу программу C++.
Но это смотрит на меня как Ваши работы программы C++, и Firefox не интерпретирует Ваш UTF-16 правильно. UTF-16 призывает к двум байтам для каждого символа. Но Firefox печатает вдвое больше символов, как он должен, таким образом, он, вероятно, пытается интерпретировать Вашу строку как UTF-8 или ASCII, которые обычно просто имеют 1 байт за символ.
Когда Вы говорите "Firefox с кодированием набора к UTF16", что Вы имеете в виду? Я скептически настроен та та работа работы.
Здесь мы сталкиваемся с небольшими используемыми свойствами локали. При выводе строки как строки (а не необработанные данные), можно заставить локаль делать соответствующее преобразование автоволшебно.
Код N.B.This не принимает во внимание edianness wchar_t символа.
#include <locale>
#include <fstream>
#include <iostream>
// See Below for the facet
#include "UTF16Facet.h"
int main(int argc,char* argv[])
{
// construct a custom unicode facet and add it to a local.
UTF16Facet *unicodeFacet = new UTF16Facet();
const std::locale unicodeLocale(std::cout.getloc(), unicodeFacet);
// Create a stream and imbue it with the facet
std::wofstream saveFile;
saveFile.imbue(unicodeLocale);
// Now the stream is imbued we can open it.
// NB If you open the file stream first. Any attempt to imbue it with a local will silently fail.
saveFile.open("output.uni");
saveFile << L"This is my Data\n";
return(0);
}
Файл: UTF16Facet.h
#include <locale>
class UTF16Facet: public std::codecvt<wchar_t,char,std::char_traits<wchar_t>::state_type>
{
typedef std::codecvt<wchar_t,char,std::char_traits<wchar_t>::state_type> MyType;
typedef MyType::state_type state_type;
typedef MyType::result result;
/* This function deals with converting data from the input stream into the internal stream.*/
/*
* from, from_end: Points to the beginning and end of the input that we are converting 'from'.
* to, to_limit: Points to where we are writing the conversion 'to'
* from_next: When the function exits this should have been updated to point at the next location
* to read from. (ie the first unconverted input character)
* to_next: When the function exits this should have been updated to point at the next location
* to write to.
*
* status: This indicates the status of the conversion.
* possible values are:
* error: An error occurred the bad file bit will be set.
* ok: Everything went to plan
* partial: Not enough input data was supplied to complete any conversion.
* nonconv: no conversion was done.
*/
virtual result do_in(state_type &s,
const char *from,const char *from_end,const char* &from_next,
wchar_t *to, wchar_t *to_limit,wchar_t* &to_next) const
{
// Loop over both the input and output array/
for(;(from < from_end) && (to < to_limit);from += 2,++to)
{
/*Input the Data*/
/* As the input 16 bits may not fill the wchar_t object
* Initialise it so that zero out all its bit's. This
* is important on systems with 32bit wchar_t objects.
*/
(*to) = L'\0';
/* Next read the data from the input stream into
* wchar_t object. Remember that we need to copy
* into the bottom 16 bits no matter what size the
* the wchar_t object is.
*/
reinterpret_cast<char*>(to)[0] = from[0];
reinterpret_cast<char*>(to)[1] = from[1];
}
from_next = from;
to_next = to;
return((from > from_end)?partial:ok);
}
/* This function deals with converting data from the internal stream to a C/C++ file stream.*/
/*
* from, from_end: Points to the beginning and end of the input that we are converting 'from'.
* to, to_limit: Points to where we are writing the conversion 'to'
* from_next: When the function exits this should have been updated to point at the next location
* to read from. (ie the first unconverted input character)
* to_next: When the function exits this should have been updated to point at the next location
* to write to.
*
* status: This indicates the status of the conversion.
* possible values are:
* error: An error occurred the bad file bit will be set.
* ok: Everything went to plan
* partial: Not enough input data was supplied to complete any conversion.
* nonconv: no conversion was done.
*/
virtual result do_out(state_type &state,
const wchar_t *from, const wchar_t *from_end, const wchar_t* &from_next,
char *to, char *to_limit, char* &to_next) const
{
for(;(from < from_end) && (to < to_limit);++from,to += 2)
{
/* Output the Data */
/* NB I am assuming the characters are encoded as UTF-16.
* This means they are 16 bits inside a wchar_t object.
* As the size of wchar_t varies between platforms I need
* to take this into consideration and only take the bottom
* 16 bits of each wchar_t object.
*/
to[0] = reinterpret_cast<const char*>(from)[0];
to[1] = reinterpret_cast<const char*>(from)[1];
}
from_next = from;
to_next = to;
return((to > to_limit)?partial:ok);
}
};
В окнах, использующих wofstream и определенный выше фасет utf16, не работает, потому что wofstream преобразует все байты со значением 0A в 2 байта 0D 0A, независимо от того, как вы передаете байт 0A, ' \ x0A ', L' \ x0A ', L' \ x000A ',' \ n ', L' \ n 'и std :: endl дают одинаковый результат. В Windows вы должны открыть файл с помощью ofstream (а не wofsteam) в двоичном режиме и записать результат так же, как это сделано в исходном сообщении.