una txt texto matriz manejo linea leer guardar desde datos como archivos archivo c++ file unicode wstring wofstream

c++ - txt - leer texto de un archivo en c



¿Cómo escribir de forma portátil std:: wstring para archivar? (9)

Tengo una wstring declarada como tal:

// random wstring std::wstring str = L"abcàdëefŸg€hhhhhhhµa";

El literal estaría codificado en UTF-8, porque mi archivo fuente es.

[EDITAR: De acuerdo con Mark Ransom, este no es necesariamente el caso, el compilador decidirá qué codificación usar. Supongamos que leo esta cadena de un archivo codificado en, por ejemplo, UTF-8]

Me gustaría mucho incluir esto en una lectura de archivo (cuando el editor de texto está configurado con la codificación correcta)

abcàdëefŸg€hhhhhhhµa

pero ofstream no es muy cooperativo (se niega a tomar los parámetros de wstring ), y wofstream supuestamente necesita conocer la configuración regional y de codificación. Sólo quiero dar salida a este conjunto de bytes. ¿Cómo hace uno normalmente esto?

EDIT: Debe ser multiplataforma y no debe confiar en que la codificación sea UTF-8 . wstring que tengo un conjunto de bytes almacenados en una wstring y quiero wstring . Muy bien podría ser UTF-16, o ASCII simple.


C ++ tiene medios para realizar una conversión de caracteres anchos a localizados en la salida o escritura de archivos. Use faceta codecvt para ese propósito.

Puede usar stdcxx.apache.org/doc/stdlibref/codecvt-byname.html estándar, o una implementation codecvt_facet no estándar.

#include <locale> using namespace std; typedef codecvt_facet<wchar_t, char, mbstate_t> Cvt; locale utf8locale(locale(), new codecvt_byname<wchar_t, char, mbstate_t> ("en_US.UTF-8")); wcout.imbue(utf8locale); wcout << L"Hello, wide to multybyte world!" << endl;

Tenga en cuenta que en algunas plataformas codecvt_byname solo puede emitir conversiones solo para las configuraciones regionales instaladas en el sistema. Por lo tanto, recomiendo buscar para "utf8 codecvt" y hacer una elección entre muchas referencias de las implementaciones de codecvt personalizadas enumeradas.

EDITAR: como OP indica que la cadena ya está codificada, todo lo que debe hacer es eliminar los prefijos L y "w" de cada token de su código.


Hay una solución (específica para Windows) que debería funcionar para usted here . Básicamente, convierta wstring a la página de códigos UTF-8 y luego use ofstream .

#include < windows.h > std::string to_utf8(const wchar_t* buffer, int len) { int nChars = ::WideCharToMultiByte( CP_UTF8, 0, buffer, len, NULL, 0, NULL, NULL); if (nChars == 0) return ""; string newbuffer; newbuffer.resize(nChars) ; ::WideCharToMultiByte( CP_UTF8, 0, buffer, len, const_cast< char* >(newbuffer.c_str()), nChars, NULL, NULL); return newbuffer; } std::string to_utf8(const std::wstring& str) { return to_utf8(str.c_str(), (int)str.size()); } int main() { std::ofstream testFile; testFile.open("demo.xml", std::ios::out | std::ios::binary); std::wstring text = L"< ?xml version=/"1.0/" encoding=/"UTF-8/"? >/n" L"< root description=/"this is a naïve example/" >/n< /root >"; std::string outtext = to_utf8(text); testFile << outtext; testFile.close(); return 0; }


No debe usar un archivo fuente codificado en UTF-8 si desea escribir código portátil. Lo siento.

std::wstring str = L"abcàdëefŸg€hhhhhhhµa";

(No estoy seguro de si esto realmente perjudica al estándar, pero creo que lo es. Pero incluso si, para estar seguro, no deberías hacerlo).

Sí, std::ostream usar std::ostream no funcionará. Hay muchas formas de convertir un wstring a UTF-8. Mi favorito es usar los componentes internacionales para Unicode . Es una gran lib, pero es genial. Obtienes muchos extras y cosas que podrías necesitar en el futuro.


Para std::wstring necesitas std::wofstream

std::wofstream f(L"C://some file.txt"); f << str; f.close();


Por mi experiencia de trabajar con diferentes codificaciones de caracteres, recomendaría que solo trate con UTF-8 en carga y ahorre tiempo. Usted se encontrará con un mundo de dolor si trata de almacenar la representación interna en UTF-8, ya que un solo carácter puede tener desde 1 byte a 4. Por lo tanto, las operaciones simples como strlen requieren mirar cada byte para decidir len en lugar de la búfer asignado (aunque puede optimizar mirando el primer byte en la secuencia char, por ejemplo, 00..7f es un solo byte char, c2..df indica un carácter de 2 bytes, etc.).

La gente suele referirse a ''cadenas Unicode'' cuando se refieren a UTF-16 y en Windows un wchar_t es un fijo de 2 bytes. En Windows creo que wchar_t es simplemente:

typedef SHORT wchar_t;

La representación completa de 4 bytes de UTF-32 rara vez se requiere y es un desperdicio, aquí lo que el Estándar Unicode (5.0) tiene que decir al respecto:

"En promedio, más del 99% de todo el UTF-16 se expresa mediante unidades de código único ... UTF-16 proporciona la combinación correcta de tamaño compacto con la capacidad de manejar el carácter ocasional fuera del BMP"

En resumen, use whcar_t como su representación interna y realice conversiones al cargar y guardar (y no se preocupe por Unicode completo a menos que sepa que lo necesita).

Con respecto a la realización de la conversión real, eche un vistazo al proyecto de ICU:

http://site.icu-project.org/



Tenga en cuenta que las secuencias de ancho solo emiten variables char *, por lo que tal vez debería intentar usar la función miembro c_str() para convertir un std::wstring y luego std::wstring al archivo. Entonces, ¿probablemente debería funcionar?



std::wstring es para algo como UTF-16 o UTF-32, no UTF-8. Para UTF-8, probablemente solo quiera usar std::string y escribir a través de std::cout . Solo FWIW, C ++ 0x tendrá literales de Unicode, lo que debería ayudar a aclarar situaciones como esta.