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

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

08.05.2021, 12:55. Показов 1159. Ответов 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
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru