С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
Модератор
Эксперт Java
 Аватар для alecss131
2848 / 1356 / 404
Регистрация: 11.08.2017
Сообщений: 4,329
Записей в блоге: 2

Как сохранить в файл русские символы из wstring?

07.10.2021, 14:15. Показов 3013. Ответов 24

Студворк — интернет-сервис помощи студентам
Есть функция сохранения вектора строк в файл (и вывода на консоль для теста)
C++
1
2
3
4
5
6
7
8
void save(std::vector<std::wstring> &data, const std::string &name) {
     std::wofstream file{name};
     for (const auto& d : data) {
         file << d << std::endl;
         std::wcout << d << std::endl;
     }
     file.close(); 
}
Но он выводит только до первого русского символа (а точнее о первой буквы "ж") и и прекращает. То есть в файле/консоли вижу только это
Code
1
2
3
4
[4e8569c]: <c=1>$+-&
[4c19406]: <c=1><b=3>
[4c19418]: <c=1><b=4>
[c0367549]: <c=1>Ha
Хотя строк там более 2 тысяч.
Для теста написал такой пример
C++
1
2
3
4
5
int main1() {
     std::wstring s{L"Нажмите START"};
     std::wcout << s << std::endl;
     return 0; 
}
Как раз таки та строка на которой ломается основная программа, и либо ничего не выводится, либо кракозябры.
Пробовал добавлять
C++
1
std::wcout.imbue(std::locale("rus.855"));
Но тогда выходит вот что:
rus ╨Э╨░╨╢╨╝╨╕╤В╨╡ START
rus.855 тЦтoт¶тОтДф'тu START
rus.866 Р
rus.1251 ╨Э╨░╨╢╨╝╨╕╤В╨╡ START
rus.1252
rus.utf8 ╨а╤Ь╨а┬░╨а┬╢╨а╤Ш╨а╤С╨бтАЪ╨а┬╡ START
Отказаться от wchar не могу, так как оригинальный файл который читаю и декодирую использует 2 байтовую кодировку. Можно и в utf8 конвертировать, но у меня и там кракозябры

вот байты из исходного файла
Code
1
48 00 61 00 36 04 3C 04 38 04 42 04 65 00 20 00 3A 04 3D 04 6F 00 3F 04 3A 04 79 00 20 00 53 00 54 00 41 00 52 00 54 00
которые надо сохранить
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
07.10.2021, 14:15
Ответы с готовыми решениями:

Широкие символы wchar_t wstring не хотят принимать русские символы
Собственно вопрос в шапке, вот примеры: std::wstring str = L&quot;блин комом&quot;; и такое: wchar_t stroka = L&quot;abcdefghijklmnopqrstuvwxyz...

Как Сохранить русские символы в текстовом файле?
вывести на экран получается, а вот сохранить не могу(( Добавлено через 45 минут Спасибо, что прочитали типа(((... разобрался с...

Как правильно передать и сохранить на сервере русские символы?
вот мой скрипт, русские буквы в $msg он пишет каракулями: &lt;? $skey = $_GET; $msg = $_GET; $bug = $_GET; $mail = $_GET; $file =...

24
736 / 700 / 110
Регистрация: 29.05.2015
Сообщений: 4,267
07.10.2021, 15:13
Набери такой текст:

C
1
std::wstring s{L"АБВГДЕЁЖЗИКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ абвгдеёжзиклмнопрстуфхцчшщъыьэюя"};
Скинь в файл и прочитай по байтам, или просто выведи на экран по байтам - и посмотри, каким буквам соответствуют какие коды. Напишешь свой декодер для таких файлов.
0
Модератор
Эксперт Java
 Аватар для alecss131
2848 / 1356 / 404
Регистрация: 11.08.2017
Сообщений: 4,329
Записей в блоге: 2
07.10.2021, 15:27  [ТС]
Цитата Сообщение от alexu_007 Посмотреть сообщение
Скинь в файл
В том то и дело что в файл ничего не пишется...
0
736 / 700 / 110
Регистрация: 29.05.2015
Сообщений: 4,267
07.10.2021, 15:27
А вообще:
Миниатюры
Как сохранить в файл русские символы из wstring?  
0
Модератор
Эксперт Java
 Аватар для alecss131
2848 / 1356 / 404
Регистрация: 11.08.2017
Сообщений: 4,329
Записей в блоге: 2
07.10.2021, 15:32  [ТС]
Цитата Сообщение от alexu_007 Посмотреть сообщение
А вообще:
При чем тут qt? Тащить 100500 метровую либу в консольную программу на пару десятков кб
0
736 / 700 / 110
Регистрация: 29.05.2015
Сообщений: 4,267
07.10.2021, 15:34
Цитата Сообщение от alecss131 Посмотреть сообщение
В том то и дело что в файл ничего не пишется...
Проще надо быть. Вот нахрена тебе это всё:
C++ (Qt)
1
for (const auto& d : data)
Напиши обычный цикл, если из такого навороченного в файл ничего не пишется.
Как видишь, в строку QString конвертируется без проблем.
0
Модератор
Эксперт Java
 Аватар для alecss131
2848 / 1356 / 404
Регистрация: 11.08.2017
Сообщений: 4,329
Записей в блоге: 2
07.10.2021, 15:37  [ТС]
Цитата Сообщение от alexu_007 Посмотреть сообщение
Проще надо быть.
И чем проще? Использовать гигантский фрейворк? Дело точно не в цикле. Qt тут совсем ни к месту. Сторонние библиотеки не использую совсем.

Добавлено через 50 секунд
Да и тему вроде не в QT создавал, чтобы мне навязывали этот фрейворк фанатики
0
736 / 700 / 110
Регистрация: 29.05.2015
Сообщений: 4,267
07.10.2021, 15:40
Цитата Сообщение от alecss131 Посмотреть сообщение
При чем тут qt? Тащить 100500 метровую либу в консольную программу на пару десятков кб
У меня только Qt, на другом проверить не могу. Но чё то мне кажется, что в std::string скопируется точно так же. Либо Qt настолько продвинутый и навороченный, что любые кодировки как семечки щёлкает.
0
Модератор
Эксперт Java
 Аватар для alecss131
2848 / 1356 / 404
Регистрация: 11.08.2017
Сообщений: 4,329
Записей в блоге: 2
07.10.2021, 15:42  [ТС]
Цитата Сообщение от alexu_007 Посмотреть сообщение
У меня только Qt, на другом проверить не могу
Большего бреда не читал, раз проект собирается значит есть и ванильный так сказать язык.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
07.10.2021, 15:51
alecss131, Запись кирилицы из std::wstring в файл
Думаю, можно начать разбираться с этой темы.
0
736 / 700 / 110
Регистрация: 29.05.2015
Сообщений: 4,267
07.10.2021, 15:53
Цитата Сообщение от alecss131 Посмотреть сообщение
Большего бреда не читал,
Ну это ж у тебя проблемы с русскими буквами, а у меня сразу всё в шоколаде получилось. Если очень нужно, перепиши оригинальный файл в текстовый (хоть и с помощью Qt), и работай как с текстовым. Я бы так сделал. Не, ну конечно дело хозяйское, если есть желание, можно и помучиться.
0
07.10.2021, 15:55

Не по теме:

Цитата Сообщение от alexu_007 Посмотреть сообщение
Ну это ж у тебя проблемы с русскими буквами, а у меня сразу всё в шоколаде получилось.
Очень удобно, не решать задачу ТС, а решить какую-то свою задачу и сказать, что все работает.
:)

0
736 / 700 / 110
Регистрация: 29.05.2015
Сообщений: 4,267
07.10.2021, 16:06
Какую свою? Вот же тестовый код ТС, который выводит кракозябры.

C
1
2
3
4
5
int main1() {
     std::wstring s{L"Нажмите START"};
     std::wcout << s << std::endl;
     return 0; 
}
Кстати, через std::string тоже кракозябры выводит. Значит QString всё-таки рулит:
Миниатюры
Как сохранить в файл русские символы из wstring?  
0
Модератор
Эксперт Java
 Аватар для alecss131
2848 / 1356 / 404
Регистрация: 11.08.2017
Сообщений: 4,329
Записей в блоге: 2
07.10.2021, 16:20  [ТС]
DrOffset, Вот это помогло
C++
1
    file.imbue(std::locale(file.getloc(), new std::codecvt_utf8_utf16<wchar_t, 0x10ffff, std::codecvt_mode(std::consume_header|std::generate_header)>));
но ругается на std::codecvt_utf8_utf16 std::codecvt_mode std::consume_header и std::generate_header то что это deprecated
Code
1
2
3
4
5
6
7
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\xlocale(259): warning C4996: 'std::codecvt_utf8_utf16<wchar_t,1114111,(std::codecvt_mode)6>': warning STL4017: std::wbuffer_convert, std::wstring_convert, and the <codecvt> header (containing std::codecvt_mode, std::codecvt_utf8, std::codecvt_utf16, and std::codecvt_utf8_utf16) are deprecated in C++17. (The std::codecvt class template is NOT deprecated.) The C++ Standard doesn't provide equivalent non-deprecated functionality; consider using MultiByteToWideChar() and WideCharToMultiByte() from <Windows.h> instead. You can define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning.
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\codecvt(428): note: see declaration of 'std::codecvt_utf8_utf16'
C:\Users\Alex\Documents\CLionProjects\map-converter\main2.cpp(89): note: see reference to function template instantiation 'std::locale::locale<std::codecvt_utf8_utf16<wchar_t,1114111,(std::codecvt_mode)6>>(const std::locale &,const _Facet *)' being compiled
        with
        [
            _Facet=std::codecvt_utf8_utf16<wchar_t,1114111,(std::codecvt_mode)6>
        ]
При чтении из файла на выходе нормальный русский язык, а вот для тестового примера кракозябры))
Если что у меня проект в виде Cmake в CLion и компилятор MSVC. На сколько знаю в исходниках CLion + Cmake хранят в utf8, а студийная ide в другой кодировке и один и тот же код с разными ide но на одном и том же копиляторе может вести себя по разному

Теперь как бы переписать код заменив deprecated
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
07.10.2021, 16:27
Цитата Сообщение от alexu_007 Посмотреть сообщение
Какую свою?
Вот задача ТС: "нужно вывести в файл UTF-16 строку стандартными средствми".

Цитата Сообщение от alexu_007 Посмотреть сообщение
Кстати, через std::string тоже кракозябры выводит.
Для корректной перекодировки нужно использовать методы QString::fromXXX в зависимости от кодировки исходной строки, с чего вы вообще решили, что побайтовое копирование будет работать?
Еще и память для второй строки выделить забыли. У вас в коде UB.

Цитата Сообщение от alecss131 Посмотреть сообщение
Теперь как бы переписать код заменив deprecated
Да, некоторое содержимое codecvt deprecated, но готовых альтернатив нет. Официальная альтернатива - реализуйте ручками нужный facet.
Так что переписать без deprecated - это реализовать нужный facet самостоятельно.
Принципы работы этой системы я объяснил в теме по ссылке. В целом ничего сложного здесь нет. Если понимать правила.
0
Just Do It!
 Аватар для XLAT
4202 / 2658 / 654
Регистрация: 23.09.2014
Сообщений: 8,960
Записей в блоге: 3
07.10.2021, 16:53
Цитата Сообщение от alecss131 Посмотреть сообщение
использует 2 байтовую кодировку
Цитата Сообщение от alecss131 Посмотреть сообщение
В том то и дело что в файл ничего не пишется...
демка на коленке:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
///----------------------------------------------------------------------------|
/// Исходник стандартно: в utf-8
///----------------------------------------------------------------------------:
#include <Windows.h>
#include <string>
#include <fstream>
#include <iostream>
#include <vector>
 
#include <fcntl.h>
#include <io.h>
 
void save(std::vector<std::wstring>& data, const std::string &name)
{
    std::ofstream file{name, std::ios::binary};
    for (const auto& d : data)
    {
        for (const auto& c : d)
        {   file.write((char*)(&c), 2);
            std::wcout << c;
        }
    }
}
 
int main()
{   setlocale(0,"");
    std::vector<std::wstring> data = {L"zЯЯЯz\n", L"zЮЮЮz\n"};
    save(data, "data.txt");
}
в файл всё пишется:
0
736 / 700 / 110
Регистрация: 29.05.2015
Сообщений: 4,267
07.10.2021, 16:53
Цитата Сообщение от DrOffset Посмотреть сообщение
с чего вы вообще решили, что побайтовое копирование будет работать?
Оно же сработало один раз при копировании из wstring.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
07.10.2021, 16:59
alecss131, да, вариант выше - это писать в бинарном режиме просто в качестве дампа байтов - тогда никакие перекодировки и facet-ы не нужны. Это будет работать, если на выходе в файле вам тоже нужен UTF-16.

Добавлено через 1 минуту
Цитата Сообщение от alexu_007 Посмотреть сообщение
Оно же сработало один раз при копировании из wstring.
Из wstring копируются не байты, а элементы типа wchart_t.
Это как бы разные вещи.
1
Just Do It!
 Аватар для XLAT
4202 / 2658 / 654
Регистрация: 23.09.2014
Сообщений: 8,960
Записей в блоге: 3
07.10.2021, 17:14
Цитата Сообщение от XLAT Посмотреть сообщение
демка
выкинуть интро цикл и всё лишнее:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
///----------------------------------------------------------------------------|
/// C++17
///----------------------------------------------------------------------------:
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
 
void save(std::vector<std::wstring>& data, const std::string &name)
{
    std::ofstream file{name, std::ios::binary};
    for (const auto& d : data)
    {   file.write((char*)(d.data()), d.size()*2);
        std::wcout << d;
    }
}
 
int main()
{   setlocale(0,"");
    std::vector<std::wstring> data = {L"1ЯЯЯz\n", L"2ЮЮЮz...\n"};
    save(data, "data.txt");
}
0
Модератор
Эксперт Java
 Аватар для alecss131
2848 / 1356 / 404
Регистрация: 11.08.2017
Сообщений: 4,329
Записей в блоге: 2
07.10.2021, 22:01  [ТС]
Я тут думаю, что сохранение в файл поможет только в случае использования как конвертер, но второе применение для моей программы еще и последующая растеризация с отрисовкой в гапи. Для чего wchar не очень подходит и стоит конвертирование вставить пораньше. В целом перейти от модели istream -> wchar -> wstring -> vector<wstring> -> wstring -> string -> ofstream к модели istream -> wchar -> char -> string -> vector<string> -> string -> ofstream
Iconv почему то не хочет работать
C++
1
2
3
4
5
6
7
8
9
10
11
char conv(iconv_t &ic, char16_t wc) {
    char *b{reinterpret_cast<char*>(&wc)};
    char c{};
    char *o{&c};
    size_t in{2};
    size_t out{1};
    errno = 0;
    size_t k{iconv(ic, &b, &in, &o, &out)};
    if(k == (size_t)-1 && errno) throw std::runtime_error("Ошибка");
    return c;
}
и где то в другом месте
C++
1
2
3
4
5
6
iconv_t ic{iconv_open("UTF-16", "UTF-8")};
//...
char16_t wc{readWChar(file)};
char c{conv(ic, wc)};
//...
iconv_close(ic);
крашит

Добавлено через 7 минут
В идеале не надо привязываться к языку, так как язык не только русский/англ

Добавлено через 3 минуты
Перепутал откуда куда
C++
1
    iconv_t ic{iconv_open("UTF-8", "UTF-16")};
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
07.10.2021, 22:01
Помогаю со студенческими работами здесь

Как перенаправить русские символы из потока вывода в файл?
Вот код: system(&quot;ipconfig &gt; text.log&quot;); В файл записываются иероглифы. Как перекодировать я не знаю. Это не помогло: ...

Как прочитать файл посредством UTL_FILE.get_line, содержайший русские символы
Имеется файл на сервере содержащие русские символы: C:\test.txt ----------------------------------- тестовый файл с русскими ...

Русские символы нормально не переносятся в сохраняемый файл
Была задача: Есть файл формата .jsx, на удалённых компьютерах. Требуется создать bat-ник для переименования одного русского слова...

В консоль русские символы выводятся правильно, а вот в файл - нет
Всем доброго времени суток!!! Вообще раньше писал на Borland C++, но тут пришлось писать на Visual C++. Суть проблемы такова: в...

Fopen не видит файл, если в его пути содержатся русские символы
Здравствуйте! Столкнулся с очень неприятной проблемой. Моя программа получает путь к нужному файлу и через строковую переменную...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru