c++ file unicode utf-8 wstring

c++ - Lea el archivo Unicode UTF-8 en wstring



file (6)

¿Cómo puedo leer un archivo Unicode (UTF-8) en wstring (s) en la plataforma de Windows?


Aquí hay una función específica de plataforma para Windows solamente:

size_t GetSizeOfFile(const std::wstring& path) { struct _stat fileinfo; _wstat(path.c_str(), &fileinfo); return fileinfo.st_size; } std::wstring LoadUtf8FileToString(const std::wstring& filename) { std::wstring buffer; // stores file contents FILE* f = _wfopen(filename.c_str(), L"rtS, ccs=UTF-8"); // Failed to open file if (f == NULL) { // ...handle some error... return buffer; } size_t filesize = GetSizeOfFile(filename); // Read entire file contents in to memory if (filesize > 0) { buffer.resize(filesize); size_t wchars_read = fread(&(buffer.front()), sizeof(wchar_t), filesize, f); buffer.resize(wchars_read); buffer.shrink_to_fit(); } fclose(f); return buffer; }

Úselo así:

std::wstring mytext = LoadUtf8FileToString(L"C://MyUtf8File.txt");

Tenga en cuenta que el archivo completo se carga en la memoria, por lo que es posible que no desee utilizarlo para archivos muy grandes.


Con el soporte de C ++ 11, puede usar std :: codecvt_utf8 facet que encapsula la conversión entre una cadena de bytes codificada UTF-8 y una cadena de caracteres UCS2 o UCS4 y que puede usarse para leer y escribir archivos UTF-8, tanto de texto como binarios. .

Para usar facet , normalmente se crea un objeto de configuración regional que encapsula información específica de la cultura como un conjunto de facetas que definen colectivamente un entorno localizado específico. Una vez que tenga un objeto de configuración regional, puede imbue su almacenamiento intermedio de secuencia con él:

#include <sstream> #include <fstream> #include <codecvt> std::wstring readFile(const char* filename) { std::wifstream wif(filename); wif.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>)); std::wstringstream wss; wss << wif.rdbuf(); return wss.str(); }

que se puede usar así:

std::wstring wstr = readFile("a.txt");

Alternativamente, puede establecer la configuración regional global de C ++ antes de trabajar con secuencias de cadenas, lo que hace que todas las llamadas futuras al constructor predeterminado std::locale devuelvan una copia de la configuración regional global de C ++ (no es necesario imbuirlas de forma explícita )

std::locale::global(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>));



Esto es un poco crudo, pero ¿qué le parece leer el archivo como viejos bytes simples y luego convertir el búfer de bytes a wchar_t *?

Algo como:

#include <iostream> #include <fstream> std::wstring ReadFileIntoWstring(const std::wstring& filepath) { std::wstring wstr; std::ifstream file (filepath.c_str(), std::ios::in|std::ios::binary|std::ios::ate); size_t size = (size_t)file.tellg(); file.seekg (0, std::ios::beg); char* buffer = new char [size]; file.read (buffer, size); wstr = (wchar_t*)buffer; file.close(); delete[] buffer; return wstr; }


Según un comentario de @ Hans Passant, la forma más simple es usar _wfopen_s . Abra el archivo con el modo rt, ccs=UTF-8 .

Aquí hay otra solución pura de C ++ que funciona al menos con VC ++ 2010:

#include <locale> #include <codecvt> #include <string> #include <fstream> #include <cstdlib> int main() { const std::locale empty_locale = std::locale::empty(); typedef std::codecvt_utf8<wchar_t> converter_type; const converter_type* converter = new converter_type; const std::locale utf8_locale = std::locale(empty_locale, converter); std::wifstream stream(L"test.txt"); stream.imbue(utf8_locale); std::wstring line; std::getline(stream, line); std::system("pause"); }

A excepción de locale::empty() (aquí locale::global() podría funcionar también) y la sobrecarga wchar_t* del constructor basic_ifstream , esto incluso debería ser bastante estándar-obediente (donde "estándar" significa C ++ 0x, por supuesto).


#include <iostream> #include <fstream> #include <string> #include <locale> #include <cstdlib> int main() { std::wifstream wif("filename.txt"); wif.imbue(std::locale("zh_CN.UTF-8")); std::wcout.imbue(std::locale("zh_CN.UTF-8")); std::wcout << wif.rdbuf(); }