Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.79/29: Рейтинг темы: голосов - 29, средняя оценка - 4.79
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915

char[] UTF8 - как прочитать и вывести на консоль

23.12.2019, 23:41. Показов 6168. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте,

Подскажите пожалуйста или направьте куда нибудь вот по такому вопросу:

Вот есть файл txt сохраненный в формате utf8, в самом файле дин символ иероглифа.

Читаю txt файл обычным способом через .read.

Получается, что этот иероглиф занимает или кодируется 6-ю байтами. Естественно на консоль не выводится, так как все 6 байт считанный в массив char - это один символ и выводить каждый элемент char в консоль нет смысла.

И вот у меня два вопроса, направьте пожалуйста в правильную строну, потому что я абсолютно не понимаю даже, что погуглить в данную тему:

1)как мне преобразовать эти считанные 6 байт, который хранятся в массиве char`ов для того, к примеру чтобы можно было провести вот такое сравнение:

char symv_utf8 = u8'思';

c моими данными считанными из файла:
C++
1
2
3
4
5
6
File_reada.seekg(0, ios::end);
Razmer = File_reada.tellg();
File_reada.seekg(0, ios::beg);
 
buff = new char[Razmer];
File_reada.read(buff, Razmer);
if(symv_utf8 == buff)
{
cout<<"Равенство"<<endl;
}

2)И как такой символ вывести на консоль ?


Я хочу понять, как это можно преобразовать без всякий функция преобразования, а как можно самому преобразовать, чтобы понять, как эта кодировка то работает.

Добавлено через 1 час 41 минуту
Цитата Сообщение от Optimus11 Посмотреть сообщение
Получается, что этот иероглиф занимает или кодируется 6-ю байтами..
Кстати, а почему получилось 6 байт ?? Разве utf8 - это не макс. 4 байта ?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.12.2019, 23:41
Ответы с готовыми решениями:

Прочитать Xml и вывести в консоль
&lt;opml version=&quot;1.1&quot;&gt; &lt;body&gt;&lt;outline text=&quot;Подписки YouTube&quot; title=&quot;Подписки YouTube&quot;&gt; &lt;outline text=&quot;The Hustle Standard&quot;...

Прочитать определенные строки из файла, занести в массив и вывести в консоль
есть файл { Имя : Александр, Фамилия : Александров, Возраст : 20 }, { Город : Москва, Дети : 2} как считать только...

UTF8 To Char
Помогите с задачкой! Мне надо сделать программу которая переводит строки из UTF8 в нормальный текст и обратно (норм текст это русские...

13
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
24.12.2019, 08:50
Цитата Сообщение от Optimus11 Посмотреть сообщение
)как мне преобразовать эти считанные 6 байт, который хранятся в массиве char`ов для того, к примеру чтобы можно было провести вот такое сравнение:
char symv_utf8 = u8'思';
Никак. В один char это не поместится.
Преобразуйте в UTF-32.

Цитата Сообщение от Optimus11 Посмотреть сообщение
без всякий функция преобразования, а как можно самому преобразовать
В UTF-32 так: Непонятки с wchar_t
Описание на примере двухбайтового символа. Чтобы сделать для любых байтов - открывайте спецификацию UTF-8.

Цитата Сообщение от Optimus11 Посмотреть сообщение
Кстати, а почему получилось 6 байт ?? Разве utf8 - это не макс. 4 байта ?
Вообще теоретически 6 байт может быть, но в вашем случае вы скорее всего неправильно подсчитали. Проверьте, нет ли BOM у этого файла. Для UTF-8 он как раз 3 байта, так что скорее всего ваш иероглиф занимает 3 байта, а не 6.

Добавлено через 2 минуты
Цитата Сообщение от Optimus11 Посмотреть сообщение
И как такой символ вывести на консоль ?
В какой ОС/среде исполнения?
1
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
24.12.2019, 09:47
C++
1
2
3
4
std::wstring
std::wchar_t
std::wcout
std::wcin
0
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
30.12.2019, 16:23  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Проверьте, нет ли BOM у этого файла. Для UTF-8 он как раз 3 байта, так что скорее всего ваш иероглиф занимает 3 байта, а не 6.
Да, Вы полностью правы, в самом начале идет три байте, говорящие о том, что текст закодирован в utf-8:
Для utf_8, BOM символ:
C++
1
EE BB BF
, что в двоичном виде:
C++
1
11101111_10111011_10111111
Ну получается, вот считываю я с блокнота символ 思 закодированный 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
File.read(buff, Razmer);
 
        char* result_char;
        result_char = new char[Razmer * 8];   // сюда запишем результат побитового чтения
        int cntr = -1;
        
        unsigned char mask = 128;  //10000000
 
        for (int x = 0; x < Razmer; x++)
        {
            for (int i = 0; i < 8; i++)
            {
                if ( (mask & (buff[x] << i)) == mask)
                {
                    cntr = cntr + 1;
                    result_char[cntr] = '1';                
                }
                else
                {
                    cntr = cntr + 1;
                    result_char[cntr] = '0';
                }
            }
        }
 
        for (int i = 0; i < Razmer * 8; i++)
        {
            cout << result_char[i];
        }
        
        delete result_char;
        result_char = nullptr;
File.close();
и вывожу биты на консоль:

C++
1
2
[111011111011101110111111]   [1110][B]0110[/B]    [10][B]000000[/B]     [10][B]011101[/B]
          BOM                уст.бит
То есть сам чистый символ получается вот такой: 0110000000011101

И вот вопрос, как его теперь сопоставить с таблицей юникод ? Это вообще можно как то сделать ? Ведь в операционных системах, как то это все работает

Цитата Сообщение от DrOffset Посмотреть сообщение
В какой ОС/среде исполнения?
[/QUOTE]

Виндовс.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
30.12.2019, 16:39
Цитата Сообщение от Optimus11 Посмотреть сообщение
2)И как такой символ вывести на консоль ?
Попробуй сделать в начале
C++
1
::SetConsoleOutputCP(CP_UTF8);
1
 Аватар для COKPOWEHEU
4079 / 2677 / 432
Регистрация: 09.09.2017
Сообщений: 11,888
30.12.2019, 16:43
C
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
 
int main(){
  setlocale(LC_ALL, "");
  FILE *pf = fopen("a.txt", "rt");
  if(pf == NULL){fprintf(stderr, "Can not open file\n"); return -1;}
  wchar_t str[100];
  fgetws(str, 99, pf);
  fclose(pf);
  wprintf(L"[%ls]\n", str);
}
Code
1
2
3
4
5
6
$ gcc main.c
$ ./a.out 
[]
$ cat a.txt 
思
В windows как обычно простой способ не работает, придется повозиться с кодировкой тамошней консоли, да еще учесть, что там wchar_t не полноценный, а 16-битный.
0
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
30.12.2019, 17:54  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Попробуй сделать в начале
C++
1
::SetConsoleOutputCP(CP_UTF8);
Не работает.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
30.12.2019, 18:46
Цитата Сообщение от Optimus11 Посмотреть сообщение
И вот вопрос, как его теперь сопоставить с таблицей юникод ?
Что значит сопоставить?

Добавлено через 20 минут
Цитата Сообщение от Optimus11 Посмотреть сообщение
И как такой символ вывести на консоль ?
Цитата Сообщение от Optimus11 Посмотреть сообщение
Виндовс.
В Windows в качестве кодировки юникода используется UTF-16. Поэтому придется сперва преобразовать UTF8 в UTF16. В приложении написанном в VS можно выводить UTF-16 с помощью wcout|wprintf, предварительно настроив консоль через функцию _setmode (кажется в последних версиях VS и Win это уже не требуется - работает сразу, но я точно не уверен).

Будет еще одна проблема. Эта проблема связана со шрифтами.
Скорее всего стандартные шрифты в русской Windows не смогут выводить иероглифы (по крайней мере не все их них). Поэтому придется найти подходящие шрифты и установить их в качестве основных для консоли.
2
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4573 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
30.12.2019, 19:18
Цитата Сообщение от Optimus11 Посмотреть сообщение
как мне преобразовать эти считанные 63 байт, который хранятся в массиве char`ов для того, к примеру чтобы можно было провести вот такое сравнение
сами символы кодируются в соответствии со следующим:

В начала файла записуются следующие байты, которые говорят о кодировке содержимого:
C
1
2
3
4
5
const char *UTF_16_BE_BOM = "\xFE\xFF";
const char *UTF_16_LE_BOM = "\xFF\xFE";
const char *UTF_8_BOM = "\xEF\xBB\xBF";
const char *UTF_32_BE_BOM = "\x00\x00\xFE\xFF";
const char *UTF_32_LE_BOM = "\xFF\xFE\x00\x00";
Ваш символ кодируется следующими байтами E6 80 9D, которые соответствуют кодировке UNICODE16, как 0x601D
А вывести у меня получилось только в MessageBox()
C
1
2
3
4
5
6
7
8
9
10
11
12
#define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers
 
#include <windows.h>
 
int main() 
{
    const char  *utf8 = "< \xE6\x80\x9d >";
    wchar_t     wstr[32];
 
    MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, 32);
    MessageBox(NULL, wstr, L"Text", MB_OK);
}
1
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4573 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
30.12.2019, 19:25
С учетом сказанного DrOffset:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#define WIN32_LEAN_AND_MEAN
 
#include <windows.h>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
 
int main() 
{
    const char  *utf8 = "< \xE6\x80\x9d >";
    wchar_t     wstr[32];
 
    MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, 32);
    _setmode(_fileno(stdout), _O_U16TEXT);
    wprintf(wstr);
}
И обязательно надо поставить соответствующий шрифт!
2
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
01.01.2020, 23:59  [ТС]
А подскажите пожалуйста, вот есть две такие строчки:

C++
1
2
3
char symv[] = u8"思";
 
char symv1[] = "Hello";
В первом случае если записать symv в текстовый файл, создается файл с кодировкой utf8, во втором случае с кодировкой ANSI, и вроде бы все логично, но вопрос - как компилятор или винда узнают, что symv - нужно сохранить и создать txt файл именно в кодировке utf8, а не файл в кодировке ANSI, но только с тремя символами, то есть где хранится эта инофрмация ? Потому как sizeof char symv[] = u8"思" равен 3ем байтам, то есть в нем указаны только биты этого иероглиф-символа и нету первых трех байт BOM информации о кодировке.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
02.01.2020, 00:08
Цитата Сообщение от Optimus11 Посмотреть сообщение
но вопрос - как компилятор или винда узнают, что symv - нужно сохранить и создать txt файл именно в кодировке utf8, а не файл в кодировке ANSI, но только с тремя символами,
Никто из них ничего не узнает. Что вы подали на запись, то и записывается.

Текстовый редактор же при открытии файла может попробовать проанализировать байты и при нахождении последовательностей похожих на utf-8, начинает сообщать вам, что в файле utf-8.
0
415 / 150 / 48
Регистрация: 02.06.2016
Сообщений: 364
04.01.2020, 09:11
Цитата Сообщение от DrOffset Посмотреть сообщение
В Windows в качестве кодировки юникода используется UTF-16. Поэтому придется сперва преобразовать UTF8 в UTF16
Цитата Сообщение от DrOffset Посмотреть сообщение
Будет еще одна проблема. Эта проблема связана со шрифтами.
Дело может быть только в шрифте? И преобразование в UTF16 лишнее? Ведь такой же код выводится.
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <stdlib.h>
using namespace std;
 
int main()
{
    const char* utf8 = "\xD0\x9F\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82\x20\xD0\xBC\xD0\xB8\xD1\x80\x21";
    system("chcp 65001");
    cout << utf8 << endl;
    return 0;
}
Миниатюры
char[] UTF8 - как прочитать и вывести на консоль  
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
04.01.2020, 10:07
Цитата Сообщение от GoshaM Посмотреть сообщение
И преобразование в UTF16 лишнее? Ведь такой же код выводится.
В этом случае преобразование в UTF16 все равно будет, просто оно будет под капотом.

Ну и: https://dev.to/mattn/please-st... 65001-27db
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
04.01.2020, 10:07
Помогаю со студенческими работами здесь

Как прочитать текстовый файл в консоль?
как на си прочитать текстовый файл в консоль??? тоесть без всяких программ,просто создал файл ,вписал код,компилировал через терминал,там...

Как правильно прочитать всю базу в консоль?
Всем привет, есть база, состоящая из id name year 1 Как ее прочитать в консоль 2 Как ее прочитать, чтобы была ровной, возможно, с...

Как прочитать переменную const char?
Здравствуйте! У меня возникла проблема при чтении текста. Как сделать так, чтобы человек ввел буквенное значение и оно записалось? ...

Как прочитать из бинарного файла тип НЕ *char
Понимаю, что ответ где-то на поверхности, но я уже задолбался искать. Гугл и все справочники, в которых я читал о функции read, приводят...

Как записать и прочитать int (4 byte) из char[]
Buffer.h #ifndef BUFFER_CPP_H #define BUFFER_CPP_H #include &lt;vector&gt; template &lt;class T&gt; class Buffer { ...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
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