Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 27, средняя оценка - 5.00
Volf 424
 Аватар для Volf 424
0 / 0 / 0
Регистрация: 18.12.2012
Сообщений: 5
#1

масив Char (Windows-1251, ASCII, UTF-8) - C++

22.12.2012, 02:24. Просмотров 3422. Ответов 8
Метки нет (Все метки)

Перехожу с мелкомяхких на linux (с Delphi на С++), так как все мои программы занимаются обработкой строк то решил сначала разобраться со строками:
  1. Windows-1251 - коды символов: 0-255 что соответствует unsigned char
  2. ASCII - коды символов: 0-127 что соответствует char (signed char)
  3. UTF-8 - совсем запутался, как с ним работать?
Программа:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;
 
int main()
{
    char s[3];
    s[0] = -47;
    s[1] = -122;
    s[2] = 0;
    cout << s << endl;
    return 0;
}
выводит символ ц (U+0446), char s[3] (-47, -121, 0) выводит символ ч (U+0447).

Как написать две функции в которых 1-я принимала масив char s[6] и выдавала код символа в HEX формате (не используемые биты заполнены нулями) и на оборот, 2-я принимала код символа в HEX формате и выдавала масив char s[6] (не используемые биты заполнены нулями) ума не приложу

Даже статья по UTF-8 в википедии не помогла.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
MrGluck
Ворчун
Эксперт CЭксперт С++
 Аватар для MrGluck
6191 / 3443 / 421
Регистрация: 29.11.2010
Сообщений: 9,123
22.12.2012, 02:26     масив Char (Windows-1251, ASCII, UTF-8) #2
Volf 424, для UTF-8 используйте wchar
Volf 424
 Аватар для Volf 424
0 / 0 / 0
Регистрация: 18.12.2012
Сообщений: 5
22.12.2012, 02:54  [ТС]     масив Char (Windows-1251, ASCII, UTF-8) #3
Цитата Сообщение от MrGluck Посмотреть сообщение
Volf 424, для UTF-8 используйте wchar
Если честно то с wchar_t в консоли у меня еще пока что не получается работать и по вики на wchar_t не очень хорошая статья для меня, не понравилось:
В Windows API, тип wchar_t именуется как WCHAR и имеет фиксированный размер 16 бит, что не позволяет кодировать весь набор символов Unicode (больше 1 миллиона). Поэтому нарушается стандарт ANSI/ISO C, который требует, чтобы символьный тип wchar_t поддерживал все представимые в системе символы в одном объекте wchar_t. По сути в WinAPI под WCHAR подразумевается 2-байтное слово из кодировки UTF-16LE (как тип WORD). Поэтому символы с кодами выше FFFF16 кодируются парой WCHAR (так называемые «суррогаты»). И всем API-функциям передаётся не количество символов, а размер символьного массива в машинных словах.

В GNU/Linux тип wchar_t имеет размер 32 бита.
поэтому вопрос встал в таком ключе.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1240 / 989 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
22.12.2012, 10:15     масив Char (Windows-1251, ASCII, UTF-8) #4
В Си/Cи++ с юникодом всё печально. Берите ICU, если не используете какой-то фреймворк вроде Qt, где юникод "искаробки" в строках.
Volf 424
 Аватар для Volf 424
0 / 0 / 0
Регистрация: 18.12.2012
Сообщений: 5
22.12.2012, 15:23  [ТС]     масив Char (Windows-1251, ASCII, UTF-8) #5
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
В Си/Cи++ с юникодом всё печально. Берите ICU, если не используете какой-то фреймворк вроде Qt, где юникод "искаробки" в строках.
Позволю не согласится, для примера: char s[5] (-16, -99, -124, -98, 0) выводит символ 𝄞 (U+01D11E), поняв как различаются 2-х байтные символы от 6-и и приведя символ к виду U+хххххх.... можно создать функции для обработки строк с нужным функционалом но как ето сделать я пока без понятия
Croessmah
Модератор
Эксперт CЭксперт С++
 Аватар для Croessmah
12498 / 7060 / 792
Регистрация: 27.09.2012
Сообщений: 17,441
Записей в блоге: 2
Завершенные тесты: 1
22.12.2012, 15:38     масив Char (Windows-1251, ASCII, UTF-8) #6
Может поможет:
Текст в памяти компьютера. Кодирование текста: ASCII и Юникод (UTF-16)
Volf 424
 Аватар для Volf 424
0 / 0 / 0
Регистрация: 18.12.2012
Сообщений: 5
23.12.2012, 02:28  [ТС]     масив Char (Windows-1251, ASCII, UTF-8) #7
Косвенно помогло, натолкнуло на мысль: Для примера возьмем char s[3] (-47, -121, 0) выводит символ ч (U+0447)
256-47=109 (11010001)
256-121=135 (10000111)
По табличке из википедии: (11010001, 10000111)=10001000111 что в HEX 0447.
Осталось придумать как это пооптимальней организовать, особенно обратное преобразование (с U+xx.... в char s[6]).
Volf 424
 Аватар для Volf 424
0 / 0 / 0
Регистрация: 18.12.2012
Сообщений: 5
25.12.2012, 00:54  [ТС]     масив Char (Windows-1251, ASCII, UTF-8) #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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#include <iostream>
using namespace std;
 
const char DecToBinTable[256][9] =
{
    "00000000","00000001","00000010","00000011","00000100","00000101","00000110","00000111",
    "00001000","00001001","00001010","00001011","00001100","00001101","00001110","00001111",
    "00010000","00010001","00010010","00010011","00010100","00010101","00010110","00010111",
    "00011000","00011001","00011010","00011011","00011100","00011101","00011110","00011111",
    "00100000","00100001","00100010","00100011","00100100","00100101","00100110","00100111",
    "00101000","00101001","00101010","00101011","00101100","00101101","00101110","00101111",
    "00110000","00110001","00110010","00110011","00110100","00110101","00110110","00110111",
    "00111000","00111001","00111010","00111011","00111100","00111101","00111110","00111111",
    "01000000","01000001","01000010","01000011","01000100","01000101","01000110","01000111",
    "01001000","01001001","01001010","01001011","01001100","01001101","01001110","01001111",
    "01010000","01010001","01010010","01010011","01010100","01010101","01010110","01010111",
    "01011000","01011001","01011010","01011011","01011100","01011101","01011110","01011111",
    "01100000","01100001","01100010","01100011","01100100","01100101","01100110","01100111",
    "01101000","01101001","01101010","01101011","01101100","01101101","01101110","01101111",
    "01110000","01110001","01110010","01110011","01110100","01110101","01110110","01110111",
    "01111000","01111001","01111010","01111011","01111100","01111101","01111110","01111111",
    "10000000","10000001","10000010","10000011","10000100","10000101","10000110","10000111",
    "10001000","10001001","10001010","10001011","10001100","10001101","10001110","10001111",
    "10010000","10010001","10010010","10010011","10010100","10010101","10010110","10010111",
    "10011000","10011001","10011010","10011011","10011100","10011101","10011110","10011111",
    "10100000","10100001","10100010","10100011","10100100","10100101","10100110","10100111",
    "10101000","10101001","10101010","10101011","10101100","10101101","10101110","10101111",
    "10110000","10110001","10110010","10110011","10110100","10110101","10110110","10110111",
    "10111000","10111001","10111010","10111011","10111100","10111101","10111110","10111111",
    "11000000","11000001","11000010","11000011","11000100","11000101","11000110","11000111",
    "11001000","11001001","11001010","11001011","11001100","11001101","11001110","11001111",
    "11010000","11010001","11010010","11010011","11010100","11010101","11010110","11010111",
    "11011000","11011001","11011010","11011011","11011100","11011101","11011110","11011111",
    "11100000","11100001","11100010","11100011","11100100","11100101","11100110","11100111",
    "11101000","11101001","11101010","11101011","11101100","11101101","11101110","11101111",
    "11110000","11110001","11110010","11110011","11110100","11110101","11110110","11110111",
    "11111000","11111001","11111010","11111011","11111100","11111101","11111110","11111111"
};
 
const char BinToHexTable[2][2][2][2][2][2][2][2][3] =
{
    "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
    "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
    "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
    "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F",
    "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F",
    "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
    "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F",
    "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F",
    "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
    "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
    "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF",
    "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
    "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF",
    "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
    "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
    "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF"
};
 
// Преобразование символа в Юникод код. (масив UTFCode должен быть размером минимум 8)
void CharToUnicod(char Char[6], char* UTFCode);
 
int main()
{
    char Code[9];
    char Char[6];
    cout << "Введите символ: ";
    cin >> Char;
    CharToUnicod(Char, Code);
    Code[8] = '\0';
    cout << "U+" << Code << endl;
    return 0;
}
 
void CharToUnicod(char Char[6], char* UTFCode)
{
    bool CodeBlock[32];
    for (int Index = 0; Index < 32; Index++)
        CodeBlock[Index] = false;
// Символы от 00000000 до 0000007F
    if ((Char[0] >= 0) && (Char[0] <= 127)) 
    {
        for (int Index = 0; Index < 7; Index++)
        {
            if (DecToBinTable[Char[0]][1 + Index] == '1')
                CodeBlock[25 + Index] = true;
        }
    }
// Символы от 00000080 до 000007FF
    if ((Char[0] >= -64) && (Char[0] <= -33))
    {
        for (int Index = 0; Index < 5; Index++)
        {
            if (DecToBinTable[256 + Char[0]][3 + Index] == '1')
                CodeBlock[21 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[1]][2 + Index] == '1')
                CodeBlock[26 + Index] = true;
        }
    }
// Символы от 00000800 до 0000FFFF
    if ((Char[0] >= -32) && (Char[0] <= -17))
    {
        for (int Index = 0; Index < 4; Index++)
        {
            if (DecToBinTable[256 + Char[0]][4 + Index] == '1')
                CodeBlock[16 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[1]][2 + Index] == '1')
                CodeBlock[20 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[2]][2 + Index] == '1')
                CodeBlock[26 + Index] = true;
        }
    }
// Символы от 00010000 до 001FFFFF
    if ((Char[0] >= -16) && (Char[0] <= -9))
    {
        for (int Index = 0; Index < 3; Index++)
        {
            if (DecToBinTable[256 + Char[0]][5 + Index] == '1')
                CodeBlock[11 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[1]][2 + Index] == '1')
                CodeBlock[14 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[2]][2 + Index] == '1')
                CodeBlock[20 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[3]][2 + Index] == '1')
                CodeBlock[26 + Index] = true;
        }
    }
// Символы от 00200000 до 03FFFFFF
    if ((Char[0] >= -8) && (Char[0] <= -5))
    {
        for (int Index = 0; Index < 2; Index++)
        {
            if (DecToBinTable[256 + Char[0]][6 + Index] == '1')
                CodeBlock[6 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[1]][2 + Index] == '1')
                CodeBlock[8 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[2]][2 + Index] == '1')
                CodeBlock[14 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[3]][2 + Index] == '1')
                CodeBlock[20 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[4]][2 + Index] == '1')
                CodeBlock[26 + Index] = true;
        }
    }
// Символы от 04000000 до FFFFFFFF
    if ((Char[0] >= -4) && (Char[0] <= -3))
    {
        for (int Index = 0; Index < 1; Index++)
        {
            if (DecToBinTable[256 + Char[0]][7 + Index] == '1')
                CodeBlock[1 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[1]][2 + Index] == '1')
                CodeBlock[2 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[2]][2 + Index] == '1')
                CodeBlock[8 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[3]][2 + Index] == '1')
                CodeBlock[14 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[4]][2 + Index] == '1')
                CodeBlock[20 + Index] = true;
        }
        for (int Index = 0; Index < 6; Index++)
        {
            if (DecToBinTable[256 + Char[5]][2 + Index] == '1')
                CodeBlock[26 + Index] = true;
        }
    }
    UTFCode[0] = BinToHexTable[CodeBlock[0]][CodeBlock[1]][CodeBlock[2]][CodeBlock[3]]
                  [CodeBlock[4]][CodeBlock[5]][CodeBlock[6]][CodeBlock[7]][0];
    UTFCode[1] = BinToHexTable[CodeBlock[0]][CodeBlock[1]][CodeBlock[2]][CodeBlock[3]]
                  [CodeBlock[4]][CodeBlock[5]][CodeBlock[6]][CodeBlock[7]][1];
    UTFCode[2] = BinToHexTable[CodeBlock[8]][CodeBlock[9]][CodeBlock[10]][CodeBlock[11]]
                  [CodeBlock[12]][CodeBlock[13]][CodeBlock[14]][CodeBlock[15]][0];
    UTFCode[3] = BinToHexTable[CodeBlock[8]][CodeBlock[9]][CodeBlock[10]][CodeBlock[11]]
                  [CodeBlock[12]][CodeBlock[13]][CodeBlock[14]][CodeBlock[15]][1];
    UTFCode[4] = BinToHexTable[CodeBlock[16]][CodeBlock[17]][CodeBlock[18]][CodeBlock[19]]
                  [CodeBlock[20]][CodeBlock[21]][CodeBlock[22]][CodeBlock[23]][0];
    UTFCode[5] = BinToHexTable[CodeBlock[16]][CodeBlock[17]][CodeBlock[18]][CodeBlock[19]]
                  [CodeBlock[20]][CodeBlock[21]][CodeBlock[22]][CodeBlock[23]][1];
    UTFCode[6] = BinToHexTable[CodeBlock[24]][CodeBlock[25]][CodeBlock[26]][CodeBlock[27]]
                  [CodeBlock[28]][CodeBlock[29]][CodeBlock[30]][CodeBlock[31]][0];
    UTFCode[7] = BinToHexTable[CodeBlock[24]][CodeBlock[25]][CodeBlock[26]][CodeBlock[27]]
                  [CodeBlock[28]][CodeBlock[29]][CodeBlock[30]][CodeBlock[31]][1];
}
Попутно просьба к модератору сменить название темы на: масив Char (ASCII, UTF-хх).
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.12.2012, 02:05     масив Char (Windows-1251, ASCII, UTF-8)
Еще ссылки по теме:

C++, UTF-8, char C++
Char *(UTF-8) -> char *(ANSI) C++
C++ Перекодировать текст с UTF-8 в ASCII
C++ Char* в число по ASCII кодам
{SetConsoleCP(1251); SetConsoleOutputCP(1251); сломал русс шрифт C++

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

Или воспользуйтесь поиском по форуму:
Avazart
 Аватар для Avazart
7037 / 5214 / 259
Регистрация: 10.12.2010
Сообщений: 22,889
Записей в блоге: 17
25.12.2012, 02:05     масив Char (Windows-1251, ASCII, UTF-8) #9
iconv
Yandex
Объявления
25.12.2012, 02:05     масив Char (Windows-1251, ASCII, UTF-8)
Ответ Создать тему
Опции темы

Текущее время: 04:01. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru