БлогNot. Записываем и читаем текстовый файл в UTF-8 из консольного приложения Windows на ...

Записываем и читаем текстовый файл в UTF-8 из консольного приложения Windows на C++

В целом, работа с кодировкой UTF-8 - не та задача, которую нужно решать в консоли С++ под Windows, хотя реализовать возможно, если применить _setmode, символы wchar_t и хитрую локаль, учитывающую переход к популярной кроссплатформенной кодировке UTF-8 от "родной" для масдайки UTF-16. Ниже показаны листинги для записи и чтения текстового файла из консольного приложения C++, собранного на пустом проекте с единственным добавленным файлом типа .cpp.

Файл данных имеет кириллическое имя и записывается в кодировке Юникода UTF-8.

/*
 исходный текст программы сохранен в кодировке UTF-8
 запись форматированного вывода в файл с помощью операции <<
 в программу добавлены строки для работы с локалью, чтобы можно было
 записать в файл русские буквы в кодировке UTF-8
*/
#include <io.h>      // для функции _setmode
#include <fcntl.h>   // для константы _O_U16TEXT
#include <fstream>   // для файлового ввода/вывода
#include <iostream>
#include <string>    // для работы с классом wstring
#include <codecvt>   // для работы с фасетом codecvt_utf8 локали
using namespace std;

int main() {
 // переключение стандартного потока вывода в формат Юникода
 _setmode(_fileno(stdout), _O_U16TEXT);
 // создаем константу, содержащую локаль 
 const locale utf8_locale = locale(locale(), new codecvt_utf8<wchar_t>());

 wchar_t ch = L'Ё'; // русская буква
 int j = 123;
 double d = 4.56;
 wstring str1 = L"String"; // две строки (одна — с латинскими буквами,
 wstring str2 = L"Строка"; // другая — с русскими) без пробелов
 wofstream outfile(L"файл данных.txt"); // создать объект класса wofstream
 outfile.imbue(utf8_locale); // связываем наш поток с нужной локалью
 outfile << ch  // вставить (записать) данные
  << L' ' // записи разделим пробелами
  << j << L' '
  << d << L' '
  << str1 << L' '
  << str2;
 outfile.close();
 wcout << L"Файл записан\n";
 return 0;
}

Прочитать записанный файл получилось следующим кодом:

/*
 исходный текст программы сохранен в кодировке UTF-8
 чтение из файла с помощью операции извлечения (>>)
 в программу добавлены строки для работы с локалью, чтобы можно было
 прочитать из файла русские буквы в кодировке UTF-8
*/
#include <io.h>      // для функции _setmode
#include <fcntl.h>   // для константы _O_U16TEXT
#include <fstream>   // для файлового ввода/вывода
#include <iostream>
#include <string>    // для работы с классом wstring
#include <codecvt>   // для работы с фасетом codecvt_utf8 локали
using namespace std;

int main() {
 // переключение стандартного потока вывода в формат Юникода
 _setmode(_fileno(stdout), _O_U16TEXT);
 // создаём константу, содержащую локаль
 const locale utf8_locale = locale(locale(), new codecvt_utf8<wchar_t>());
 wchar_t ch;
 int j;
 double d;
 wstring str1;
 wstring str2;
 wifstream infile(L"файл данных.txt"); // создать объект класса wifstream
 infile.imbue(utf8_locale);  // связываем наш поток с нужной локалью
 infile >> ch >> j >> d >> str1 >> str2;  // извлечь (прочесть) из него данные
 wcout << ch << endl                      // вывести данные на экран
  << j << endl
  << d << endl
  << str1 << endl
  << str2 << endl;
 return 0;
}

Проверено в консолях актуальных сборок Visual Studio 2019 и 2022. На одном из компьютеров тупой "Касперский" ругался на слинкованное приложение как на троян. :)

В верхнем меню Studio желательно установить опцию "Сохранять документы в формате Юникод" по пути Средства - Параметры - Окружение - Документы.

02.10.2023, 18:41 [773 просмотра]


теги: c++ windows textprocessing studio

показать комментарии (1)