Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 22.11.2020
Сообщений: 42

Чтение и запись многобайтовых строк

08.05.2021, 12:55. Показов 1201. Ответов 10

Студворк — интернет-сервис помощи студентам
Приветствую )
Поднимаю вечную проблему - проблему русского текста в C++

Задача:
Считать ввод с консоли (русский/английский) и в точности записать в файл в кодировке UTF-8

За дело !
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <io.h>
#include <fcntl.h>
#include <codecvt>
 
using namespace std;
 
int main(int, char **) {
 
    /** -*-> Установка русской локали -*-> */
    try {
        locale::global(locale{"ru_RU.UTF8"}); /// OS Linux (GCC)
    } catch (...) {
        setlocale(LC_ALL, "Russian"); /// OS Windows (MinGW)
    }
 
    /** -*-> тип данных потоков в UNICODE char16_t -*-> */
    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stdin), _O_U16TEXT);
    _setmode(_fileno(stderr), _O_U16TEXT);
 
    /** -*-> заполнение вектора введёнными строками -*-> */
    vector<wstring> buffer{};
    for (wstring str{}; getline(wcin, str);) buffer.push_back(str);
 
    /** -*-> поток вывода в файл -*-> */
    string path{"test.txt"};
    ios::openmode mode{ios::out | ios::trunc | ios::binary};
    wfstream oStream{path, mode};
 
    /** -*-> наполняем поток локалью с фасетом, способным преобразовать наш код (UTF-16) в UTF-8 или UTF-16 -*-> */
    oStream.imbue(locale{locale{}, new codecvt_utf8_utf16<wchar_t>});
 
    /** -*-> вывод из вектора в файл -*-> */
    ostream_iterator<wstring, wchar_t> itOut{oStream, L"\n"}; /// <- !!! Строчка, затем \n и так далее
    move(begin(buffer), end(buffer), itOut);
 
    system("pause");
 
    return 0;
}
Ввод в консоль:
Привет как делы ?
Да блин, то \n многовато !
(комбинация ctrl + z)

Результат в файле:
Привет как делы ?

Да блин, то \n многовато !

Итого:
После каждой строчки взялся дополнительный перенос, сразу скажу, что я уже перепробовал ну очень многое, тут я думаю у меня проблема в самом понимании как работают:
C++
1
2
3
4
5
6
7
8
9
10
    try {
        locale::global(locale{"ru_RU.UTF8"}); /// OS Linux (GCC)
    } catch (...) {
        setlocale(LC_ALL, "Russian"); /// OS Windows (MinGW)
    }
 
    /** -*-> тип данных потоков в UNICODE char16_t -*-> */
    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stdin), _O_U16TEXT);
    _setmode(_fileno(stderr), _O_U16TEXT);
Но как я ни старался у меня не получилось избавиться от лишних строк... Да так избавиться чтобы работать с русским текстом.
Конечно если убрать три _setmode лишние переносы пропадают, но и вместо русского текста мешанина из кодировок.
ПРОБЛЕМА В НЕПОНИМАНИИ КАК РАБОТАТЬ С КОДИРОВКАМИ В С++
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.05.2021, 12:55
Ответы с готовыми решениями:

Запись и чтение wchar_t строк
Всем добрый вечер. есть wchar_t str, как её запихнуть в текстовый файл используя потоки, а потом считать? и есть возможность...

Чтение из файла и запись строк в массив
Здравствуйте! Сейчас пишу свою реализацию алгоритма FIFS и возникла проблема с записью данных из файла в массив. Формат входных данных в...

Работа с файлами. Запись и чтение строк
Добавляю строку в файл &quot;text.txt&quot; а потом пытаюсь получить количество строк в этом файле.. Проблема заключается в том что добавляю...

10
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
08.05.2021, 13:34
sadomazo228, а почему вы выходной файл в binary-моде открываете? В результате у вас L"\n" в файл попадает как 0x0A. И чем смотрите результат в файле? Может просмотрщик своеобразно отображает одинокий код 0x0A.

Попробуйте для файла дефолтный text-mode.

Я размножения концов строк в вашей программе не наблюдаю ни так, ни так.
0
0 / 0 / 0
Регистрация: 22.11.2020
Сообщений: 42
08.05.2021, 13:37  [ТС]
Цитата Сообщение от L0M Посмотреть сообщение
Я размножения концов строк в вашей программе не наблюдаю ни так, ни так.
А каким блокнотом вы открывали документ ?
Хотя тут похоже надо спросить какая у вас ОС ?
0
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
08.05.2021, 13:41
sadomazo228, Win10, Notepad2 4.2.25 и Far Manager, version 3.0 (build 4900) x64 (просмотр в тексте и в кодах).
0
0 / 0 / 0
Регистрация: 22.11.2020
Сообщений: 42
08.05.2021, 13:50  [ТС]
Ну у меня так же, проклятье !

Добавлено через 1 минуту
Дело даже в том, что если не в файл выводить например, а в консоль, то у меня тоже будут дополнительные пустые переносы строк (

Добавлено через 6 минут
Ну кстати на ваш вопрос почему именно ios::binary, да просто потому что, как написал, так и будет вводиться, без дополнительных преобразований (это по книге).
0
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
08.05.2021, 13:52
sadomazo228, ваш test.txt прикрепите к сообщению.
А компилятор у вас какой? Я смотрю под Visual Studio 2019.

Добавлено через 2 минуты
Цитата Сообщение от sadomazo228 Посмотреть сообщение
Ну кстати на ваш вопрос почему именно ios::binary, да просто потому что как написал, так и будет, без дополнительных преобразований
Это да, но вы работаете с текстом. Может эти дополнительные преобразования как раз и нужны? Вы попробуйте в текстовом режиме файл писать.
0
0 / 0 / 0
Регистрация: 22.11.2020
Сообщений: 42
08.05.2021, 14:01  [ТС]
У меня Clion 2020.1

Добавлено через 2 минуты
Только что проверил без бинарного мода, то же самое

Добавлено через 4 минуты
И компилятор у меня такой же как и у вас раз мы оба на Win10 -> MinGW

Добавлено через 1 минуту
Мне вот ещё что интересно, у тебя вот эта строча выбросит исключение ?
C++
1
locale::global(locale{"ru_RU.UTF8"});
0
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
08.05.2021, 14:11
Цитата Сообщение от sadomazo228 Посмотреть сообщение
И компилятор у меня такой же как и у вас раз мы оба на Win10 -> MinGW
Не-а. Компилятор у меня майкрософтовский.
Цитата Сообщение от sadomazo228 Посмотреть сообщение
Мне вот ещё что интересно, у тебя вот эта строча выбросит исключение ?
Не выбрасывает.

Файлик свой выходной прикрепите к сообщению.

Результат работы вашей программы на моей системе с выводом в файл в текстовом режиме прикрепил.
Вложения
Тип файла: txt test.txt (151 байт, 2 просмотров)
0
0 / 0 / 0
Регистрация: 22.11.2020
Сообщений: 42
09.05.2021, 03:45  [ТС]
Вот, скидываю свой файл...

Короче... я решил проблему оборачиванием wcin в манипулятор ws -> ws(wcin)
Как результат wcin фильтрует пробельные символы в начале строки и в конце.
А ТЕПЕРЬ ВНИМАТЕЛЬНО !
Но раз в строке сохраняется \n, то я могу обойтись без \n в самом итераторе:
C++
1
ostream_iterator<wstring, wchar_t> itOut{oStream}; /// <- !!! без второго аргумента L"\n"
Ожидаемый результат:
Каждая строчка на своём месте... Потому что у каждой строчки уже должен быть свой \n

У меня фактический результат:
Всё в одну строчку

Исходник (результат исходника скину в файле withOutN.txt):
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <io.h>
#include <fcntl.h>
#include <codecvt>
 
using namespace std;
 
int main(int, char **) {
 
    /** -*-> Установка русской локали -*-> */
    try {
        locale::global(locale{"ru_RU.UTF8"}); /// OS Linux (GCC)
    } catch (...) {
        setlocale(LC_ALL, "Russian"); /// OS Windows (MinGW)
    }
 
    /** -*-> тип данных потоков в UNICODE char16_t -*-> */
    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stdin), _O_U16TEXT);
    _setmode(_fileno(stderr), _O_U16TEXT);
 
    /** -*-> заполнение вектора введёнными строками -*-> */
    vector<wstring> buffer{};
    for (wstring str{}; getline(wcin, str);) buffer.push_back(str); /// <- !!! В конце str \n уже есть от getline()
 
    /** -*-> поток вывода в файл -*-> */
    string path{"withOutN.txt"};
    ios::openmode mode{ios::out | ios::trunc | ios::binary};
    wfstream oStream{path, mode};
 
    /** -*-> наполняем поток локалью с фасетом, способным преобразовать наш код (UTF-16) в UTF-8 или UTF-16 -*-> */
    oStream.imbue(locale{locale{}, new codecvt_utf8_utf16<wchar_t>});
 
    /** -*-> вывод из вектора в файл -*-> */
    ostream_iterator<wstring, wchar_t> itOut{oStream}; /// <- !!! Строчка, затем \n и так далее
    move(begin(buffer), end(buffer), itOut);
 
    system("pause");
 
    return 0;
}
Вложения
Тип файла: txt test.txt (140 байт, 3 просмотров)
Тип файла: txt withOutN.txt (137 байт, 5 просмотров)
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
09.05.2021, 08:07
getline() отбрасывает \n.
0
0 / 0 / 0
Регистрация: 22.11.2020
Сообщений: 42
09.05.2021, 08:57  [ТС]
А у меня получается не отбросила ? Но как это возможно
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.05.2021, 08:57
Помогаю со студенческими работами здесь

Запись и чтение wchar_t строк
Всем добрый вечер. есть wchar_t str, как её запихнуть в текстовый файл используя потоки, а потом считать? и есть возможность...

Чтение строк и запись в файл
Задача: считать 1000 строк с файла в List&lt;string&gt;, преобразовать этот лист в массив байтов, записать массив байтов в файл, откуда...

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

Чтение и запись строк из txt файлов
доброе время суток.. кто сможет написать простенькую прогу? функционал такой... есть текстовики 3-6 текстовиков txt1,txt2,txt3... я...

Чтение 2 строк из файла и запись в массив
Если строки стандартной длины - 255 символов, то проблем нет... проблема возникает, когда строка может содержать довольно больше...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru