Как я могу прочитать файл Unicode (UTF-8) в wstring
(s) на платформе Windows?
Прочитать файл Unicode UTF-8 в строку wstring
Ответы (6)
С поддержкой C ++ 11 вы можете использовать фасет std :: codecvt_utf8 , который инкапсулирует преобразование между строка байтов в кодировке UTF-8 и строка символов UCS2 или UCS4 и , которые могут использоваться для чтения и записи файлов UTF-8, как текстовых, так и двоичных.
Чтобы использовать фасет, вы обычно создаете объект языкового стандарта , который инкапсулирует информацию, относящуюся к региональным параметрам, в виде набора аспектов, которые в совокупности определяют конкретную локализованную среду. Создав объект языкового стандарта, вы можете может наполнить им буфер потока:
#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();
}
который можно использовать так:
std::wstring wstr = readFile("a.txt");
В качестве альтернативы вы можете установить глобальный языковой стандарт C ++, прежде чем работать со строковыми потоками, которые вызывают все будущие вызовы std::locale
конструктора по умолчанию для возврата копии глобального языкового стандарта C ++ (в этом случае вам не нужно явно добавлять его в буферы потока):
std::locale::global(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>));
new codecvt_utf8
требует соответствующего delete
?
- person Dmitri Nesteruk; 05.09.2016
Согласно комментарию @Hans Passant, самый простой способ - использовать _wfopen_s. Откройте файл в режиме rt, ccs=UTF-8
.
Вот еще одно чистое решение на C ++, которое работает как минимум с 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");
}
За исключением locale::empty()
(здесь locale::global()
также может работать) и wchar_t*
перегрузки конструктора basic_ifstream
, это даже должно быть достаточно совместимо со стандартом (где «стандарт», конечно же, означает C ++ 0x).
delete converter
?
- person Mikhail; 28.09.2013
Вот функция, зависящая от платформы, только для Windows:
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;
}
Используйте так:
std::wstring mytext = LoadUtf8FileToString(L"C:\\MyUtf8File.txt");
Обратите внимание, что весь файл загружается в память, поэтому вы можете не использовать его для очень больших файлов.
Simply using _wfopen has no effect on the coded character set used in the file stream.
- person Hans Passant; 23.01.2011
t
в режиме, а также ccs=UTF-8
, символы будут преобразованы по мере их чтения в поток и из потока.
- person AshleysBrain; 23.01.2011
_wfopen
без спецификатора режима ccs=
. Вам нужны оба _wfopen
(согласно руководству предпочтительнее _wfopen_s
) и ccs=UTF-8
.
- person Philipp; 23.01.2011
Этот вопрос был рассмотрен в Не знаете, что такое std :: wstring, UTF-16, UTF-8 в C ++ и отображение строк в графическом интерфейсе Windows. В общем, wstring основан на стандарте UCS-2, который является предшественником UTF-16. Это строго двухбайтовый стандарт. Я считаю, что это относится к арабскому языку.
wstring
- это просто массив 16-битных целых чисел в Windows. Вы можете хранить в нем данные UCS-2 или UTF-16 или что угодно. В настоящее время большинство API-интерфейсов Windows принимают строки UTF-16.
- person Philipp; 23.01.2011
wstring
, если рассматривать ее как строку UTF-16. Для кодовых точек, отличных от BMP, потребуется две кодовых единицы, но в этом нет ничего плохого.
- person Philipp; 23.01.2011
wstring
.
- person David Heffernan; 23.01.2011
iostreams
поддерживает какой-либо Unicode, кроме разрешения имен файлов Unicode. Все решения для использования Unicode в C ++ по сути являются чистыми решениями C, либо с использованием Windows API напрямую, либо с использованием нестандартных расширений библиотеки C.
- person Philipp; 23.01.2011
Это немного сыро, но как насчет того, чтобы прочитать файл как простые старые байты, а затем преобразовать байтовый буфер в wchar_t *?
Что-то вроде:
#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;
}