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

Перевод символа в Юникод - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 41, средняя оценка - 4.95
Danvern
 Аватар для Danvern
40 / 39 / 3
Регистрация: 22.06.2010
Сообщений: 415
Записей в блоге: 1
24.06.2011, 12:05     Перевод символа в Юникод #1
Подскажите пожалуйста как закодировать например вот такую строку
привет
что бы она стала такой?
%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82
Википедии увидел такой алгоритм:
1)Переводим символ в Юникод.
2)затем разделяем каждый байт знаком процента
подскажите как сделать первый пункт?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.06.2011, 12:05     Перевод символа в Юникод
Посмотрите здесь:

Перевод символа в нижний регистр C++
Юникод в Си++ C++
Перевод символа в число C++
C++ Юникод. Шахматные символы
Перевод символа в число и обратно. C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
mimicria
return (true);
 Аватар для mimicria
1956 / 1093 / 91
Регистрация: 19.04.2011
Сообщений: 2,344
24.06.2011, 12:23     Перевод символа в Юникод #2
Цитата Сообщение от Danvern Посмотреть сообщение
подскажите как сделать первый пункт?
int MultiByteToWideChar(

UINT CodePage, // code page
DWORD dwFlags, // character-type options
LPCSTR lpMultiByteStr, // address of string to map
int cchMultiByte, // number of characters in string
LPWSTR lpWideCharStr, // address of wide-character buffer
int cchWideChar // size of buffer
);
oxotnik
 Аватар для oxotnik
1584 / 1061 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
24.06.2011, 12:29     Перевод символа в Юникод #3
http://www.codeguru.com/cpp/cpp/cpp_...icle.php/c4029
xAtom
 Аватар для xAtom
910 / 735 / 60
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
24.06.2011, 12:35     Перевод символа в Юникод #4
Цитата Сообщение от mimicria Посмотреть сообщение
MultiByteToWideChar(
Только для Windows.

Вот консольное.

C++
1
2
3
4
5
6
    wchar_t   wstr[255];
    const char* str = "Ansi to Unicode";
 
    mbstowcs(wstr, str, strlen(str));  // конвертация
 
    wprintf(L"convert: %s", wstr);
Danvern
 Аватар для Danvern
40 / 39 / 3
Регистрация: 22.06.2010
Сообщений: 415
Записей в блоге: 1
24.06.2011, 12:49  [ТС]     Перевод символа в Юникод #5
попробовал вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <stdio.h>
using namespace std;
 
int main()
{
        wchar_t   wstr[255];
        char str[2] = "п";
        mbstowcs(wstr, str, sizeof(str));  // конвертация
        wprintf(L"convert: %X\n", wstr);
        getchar();
}
выводит вот это 12fd7c
а по идее должно вывестись вот это D0BF
может быть я что не правильно сделал..
Danvern
 Аватар для Danvern
40 / 39 / 3
Регистрация: 22.06.2010
Сообщений: 415
Записей в блоге: 1
25.06.2011, 14:41  [ТС]     Перевод символа в Юникод #6
реализовал вот так
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
#include <iostream>
#include <stdio.h>
using namespace std;
 
char * UrlEncode(char * c)
{
    const char lUrlDe[] = " \n\"#%+;<>@\\`ё№АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя";
 
    char * lUrlEn[] = {
                "%20","%0D","%22","%23","%25","%2B","%3B","%3C","%3E","%40","%5C","%60","%D1%91","%E2%84%96","%D0%90","%D0%91",
                "%D0%92","%D0%93","%D0%94","%D0%95","%D0%96","%D0%97","%D0%98","%D0%99","%D0%9A","%D0%9B","%D0%9C",
                "%D0%9D","%D0%9E","%D0%9F","%D0%A0","%D0%A1","%D0%A2","%D0%A3","%D0%A4","%D0%A5","%D0%A6","%D0%A7",
                "%D0%A8","%D0%A9","%D0%AA","%D0%AB","%D0%AC","%D0%AD","%D0%AE","%D0%AF","%D0%B0","%D0%B1","%D0%B2",
                "%D0%B3","%D0%B4","%D0%B5","%D0%B6","%D0%B7","%D0%B8","%D0%B9","%D0%BA","%D0%BB","%D0%BC","%D0%BD",
                "%D0%BE","%D0%BF","%D1%80","%D1%81","%D1%82","%D1%83","%D1%84","%D1%85","%D1%86","%D1%87","%D1%88",
                "%D1%89","%D1%8A","%D1%8B","%D1%8C","%D1%8D","%D1%8E","%D1%8F"
                                   };   
    int size = 128 * 128;
    char * p = new char[size];
    memset(p,0,sizeof(p));
    char temp[2];
    bool fin;
 
    for(int k = 0;k < (int)strlen(c);k++)
    {
        fin = true;
        for(int i = 0; i < sizeof(lUrlDe);i++)
        {
            if(c[k] == lUrlDe[i] && size > (int)strlen(p))
            {
                strcat(p,lUrlEn[i]);
                fin = false;
            }
        }
        if(fin)
        {
            if(size > (int)strlen(p))
            {
                memset(temp,0,2);
                temp[0] = c[k];
                strcat(p,temp);
            }
        }
    }
    return p;
}
 
int main()
{
    cout << UrlEncode("привет")  << endl;
    getchar();
    return 0;
}
oxotnik
 Аватар для oxotnik
1584 / 1061 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
25.06.2011, 21:40     Перевод символа в Юникод #7
через ассоциативный массив типа std::map не легче было бы?
Danvern
 Аватар для Danvern
40 / 39 / 3
Регистрация: 22.06.2010
Сообщений: 415
Записей в блоге: 1
27.06.2011, 08:15  [ТС]     Перевод символа в Юникод #8
не не легче... Просто я с ними не разу не работал...
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,210
Завершенные тесты: 1
27.06.2011, 21:55     Перевод символа в Юникод #9
Цитата Сообщение от Danvern Посмотреть сообщение
C++
1
2
char * p = new char[size];
memset(p,0,sizeof(p));
sizeof(указатель_на_массива) совсем не то же самое что sizeof(массив)

пример:
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
int main()
{
    const int size = 128 * 128;
    char buff[size];
    char * p = buff;
    std::cout << sizeof(p) << std::endl;
    std::cout << sizeof(buff) << std::endl;
    return 0;
}
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,210
Завершенные тесты: 1
30.06.2011, 13:15     Перевод символа в Юникод #10
Danvern, тут нужно отметить что использование данной функции накладывает на клиентский код необходимость в освобождении выделенной памяти когда она уже ненужна иначе при каждом вызове будет утечка памяти, причем весьма нехилая:
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
#include <iostream>
using std::cout;
using std::endl;
 
// ... UrlEncode()
 
int main()
{
    // бажный код
    cout << UrlEncode("привет") << endl;
    cout << UrlEncode("привет") << endl;
    cout << UrlEncode("привет") << endl;
    cout << UrlEncode("привет") << endl;
    cout << UrlEncode("привет") << endl;
    // имеем утечку памяти (5 * 128 * 128) байт 
 
    // нужно чтобы клиент Вашей функции сам освобождал память:
    char * p = 0;
    
    p = UrlEncode("привет");
    cout << p << endl;
    delete[] p;
 
    p = UrlEncode("привет");
    cout << p << endl;
    delete[] p;
 
    p = UrlEncode("привет");
    cout << p << endl;
    delete[] p;
 
    p = UrlEncode("привет");
    cout << p << endl;
    delete[] p;
 
    p = UrlEncode("привет");
    cout << p << endl;
    delete[] p;
 
    return 0;
}
Danvern
 Аватар для Danvern
40 / 39 / 3
Регистрация: 22.06.2010
Сообщений: 415
Записей в блоге: 1
05.07.2011, 18:59  [ТС]     Перевод символа в Юникод #11
вот ещё один вариант написал...
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
#include <iostream>
#include <stdio.h>
using namespace std;
 
int main()
{
    setlocale(0,"");
    char s[] = "hello";
    char temp[6];
    int hos,los ;
    long int sym;
    char * result = new char[strlen(s) * 6 + 1];
    wchar_t * sw = new wchar_t[strlen(s)];
    memset(result,0,strlen(s) * 6  + 1);
    memset(sw,0,strlen(s));
    mbstowcs(sw,s,strlen(s));
 
    for(int i = 0;i < strlen(s);i++)
    {
        if((int)sw[i] >= 128 && (int)sw[i] <= 2047)
        {
            hos = sw[i] >> 6;
            los = (hos << 6) ^ sw[i];
            sym = ( ( ( ( ( 6 << 5 ) ^ hos ) << 2 ) ^ 2 ) << 6 ) ^ los;
 
            memset(temp,0,sizeof(temp));
            sprintf(temp,"%X",sym);
            result[strlen(result)] = '%';
            result[strlen(result)] = temp[0];
            result[strlen(result)] = temp[1];
            result[strlen(result)] = '%';
            result[strlen(result)] = temp[2];
            result[strlen(result)] = temp[3];
        }
    }
    cout << result << endl;
 
    delete[] sw;
    delete[] result;
 
    getchar();
    return 0;
}
подходит только для :
кириллица, расширенная латиница, арабский, армянский, греческий, еврейский и коптский алфавит; сирийское письмо, тана, нко; МФА; некоторые знаки препинания
для других символов смотреть сюда http://ru.wikipedia.org/wiki/UTF-8
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,210
Завершенные тесты: 1
05.07.2011, 19:21     Перевод символа в Юникод #12
1. strlen(s) - выполняется очень много раз, при том, что s не изменяется;
2. strlen(result) - зачем пробегаться по строке каждый раз 0 до последнего символа, вычисляя длину результирующей строки, если на каждой итерации цикла она изменяется либо на 6 символов, либо на 1;
3. Ужасно много магических чисел в коде.

Кстати, я ожидаю от алгоритма UrlEncode("hello world"), что он мне вернет строку "hello%20world", посмотрите, что у Вас возвращает. Так и задумано?
Danvern
 Аватар для Danvern
40 / 39 / 3
Регистрация: 22.06.2010
Сообщений: 415
Записей в блоге: 1
05.07.2011, 19:26  [ТС]     Перевод символа в Юникод #13
1. strlen(s) - исправлю
2. strlen(result) - зачем пробегаться по строке каждый раз 0 до последнего символа, вычисляя длину результирующей строки, если на каждой итерации цикла она изменяется либо на 6 символов, либо на 1;
3. Ужасно много магических чисел в коде.
вы про это sym = ( ( ( ( ( 6 << 5 ) ^ hos ) << 2 ) ^ 2 ) << 6 ) ^ los;

Цитата Сообщение от schdub Посмотреть сообщение
Кстати, я ожидаю от алгоритма UrlEncode("hello world"), что он мне вернет строку "hello%20world", посмотрите, что у Вас возвращает. Так и задумано?
я же написал

Цитата Сообщение от Danvern Посмотреть сообщение
подходит только для :
кириллица, расширенная латиница, арабский, армянский, греческий, еврейский и коптский алфавит; сирийское письмо, тана, нко; МФА; некоторые знаки препинания
для других символов смотреть сюда http://ru.wikipedia.org/wiki/UTF-8
или просто добавить в цикл вот это
C++
1
2
3
4
5
6
7
8
9
10
        if((int)sw[i] <= 127)
        {
            memset(temp,0,sizeof(temp));
 
            sprintf(temp,"%X",(int)sw[i]);
 
            result[strlen(result)] = '%';
            result[strlen(result)] = temp[0];
            result[strlen(result)] = temp[1];
        }
например для проверки http://www.google.ru/search?client=o...hannel=suggest
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,210
Завершенные тесты: 1
05.07.2011, 19:32     Перевод символа в Юникод #14
Цитата Сообщение от Danvern Посмотреть сообщение
или просто добавить в цикл вот это
нет, если символ является ASCII, то его необходимо скопировать в результирующую строку без изменений:
нужно: "hello%20world"
по вашему алгоритму: "%68%65%6C%6C%6F%20%77%6F%72%6C%64"
Danvern
 Аватар для Danvern
40 / 39 / 3
Регистрация: 22.06.2010
Сообщений: 415
Записей в блоге: 1
05.07.2011, 19:34  [ТС]     Перевод символа в Юникод #15
ну пока ещё не дошёл до этого а просто решил обезопасить сразу все символы
и гугл вроде это съедает))
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,210
Завершенные тесты: 1
05.07.2011, 19:46     Перевод символа в Юникод #16
Цитата Сообщение от Danvern Посмотреть сообщение
вы про это
не только:

Цитата Сообщение от Danvern Посмотреть сообщение
char temp[6];
Цитата Сообщение от Danvern Посмотреть сообщение
char * result = new char[strlen(s) * 6 + 1];
Цитата Сообщение от Danvern Посмотреть сообщение
memset(result,0,strlen(s) * 6 + 1);
Цитата Сообщение от Danvern Посмотреть сообщение
hos = sw[i] >> 6;
los = (hos << 6) ^ sw[i];
почему 6? как связаны эти куски? это одно понятие? что если необходимо будет изменить это значение.

Цитата Сообщение от Danvern Посмотреть сообщение
if((int)sw[i] >= 128 && (int)sw[i] <= 2047)
что это за значения ?
Danvern
 Аватар для Danvern
40 / 39 / 3
Регистрация: 22.06.2010
Сообщений: 415
Записей в блоге: 1
05.07.2011, 20:17  [ТС]     Перевод символа в Юникод #17
это все вики педии написано

Цитата Сообщение от schdub Посмотреть сообщение
почему 6? как связаны эти куски? это одно понятие? что если необходимо будет изменить это значение.
потому что каждая буква например "п" в url кодировке "%D0%BF" собственно в массиве должно быть в 6 раз больше места чем в начальном.
Цитата Сообщение от schdub Посмотреть сообщение
что это за значения ?
вот из википедии
0x00000080 — 0x000007FF (128 - 2047) 110xxxxx 10xxxxxx кириллица, расширенная латиница, арабский, армянский, греческий, еврейский и коптский алфавит; сирийское письмо, тана, нко; МФА; некоторые знаки препинания
Добавлено через 24 минуты
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
#include <iostream>
#include <stdio.h>
using namespace std;
 
int main()
{
    setlocale(0,"");
    system("cls");
 
    char s[] = "hello Word";
    char illegalChar[] = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
    bool whatIllegal = false;
    char temp[6];
    int hos , los ,lenStr = strlen(s);
    long int sym;
    char * result = new char[lenStr * 6 + 1];
    wchar_t * sw = new wchar_t[lenStr + 1];
 
    memset(result,0,lenStr * 6  + 1);
    memset(sw,0,lenStr + 1);
 
    mbstowcs(sw,s,lenStr);
 
    for(int i = 0;i < (int)strlen(s);i++)
    {
        
        if((int)sw[i] <= 127)
        {
            memset(temp,0,sizeof(temp));
            for(int k = 0;k < sizeof(illegalChar);k++)
            {
                if(illegalChar[k] == sw[i])
                {
                    whatIllegal = true;
                    break;
                }
            }
 
            lenStr = strlen(result);
 
            if(!whatIllegal)
            {
                sprintf(temp,"%X",(int)sw[i]);
                result[lenStr] = '%';
                result[lenStr + 1] = temp[0];
                result[lenStr + 2] = temp[1];
            }
            else
            {
                result[lenStr] = sw[i];
                whatIllegal = false;
            }
        }
 
        if((int)sw[i] >= 128 && (int)sw[i] <= 2047)
        {
            hos = sw[i] >> 6;
            los = (hos << 6) ^ sw[i];
            sym = ( ( ( ( ( 6 << 5 ) ^ hos ) << 2 ) ^ 2 ) << 6 ) ^ los;
 
            memset(temp,0,sizeof(temp));
 
            sprintf(temp,"%X",sym);
 
            lenStr = strlen(result);
            result[lenStr] = '%';
            result[lenStr + 1] = temp[0];
            result[lenStr + 2] = temp[1];
            result[lenStr + 3] = '%';
            result[lenStr + 4] = temp[2];
            result[lenStr + 5] = temp[3];
        }
    }
    cout << result << endl;
 
    delete[] sw;
    delete[] result;
 
    getchar();
    return 0;
}
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,210
Завершенные тесты: 1
05.07.2011, 21:18     Перевод символа в Юникод #18
на будущее:
Цитата Сообщение от Danvern Посмотреть сообщение
C
1
memset(sw,0,lenStr + 1);
скорее всего неверно. обратите внимание на третий аргумент (должен быть указан размер в байтах). но т.к.:
Цитата Сообщение от Danvern Посмотреть сообщение
C
1
wchar_t * sw = new wchar_t[lenStr + 1];
lenStr - количество символов во входной строке, каждый символ которой равен 1 байту, но sizeof(wchar_t) == 2 байтам
таким образом нужно:
Цитата Сообщение от Danvern Посмотреть сообщение
C
1
memset(sw,0, sizeof(*sw) * (lenStr + 1));
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
05.07.2011, 21:57     Перевод символа в Юникод #19
Цитата Сообщение от schdub Посмотреть сообщение
но sizeof(wchar_t) == 2 байтам
Главное на это не закладываться (чего, впрочем, в рекомендуемом примере и нет), так как у меня, например, sizeof(wchar_t) == 4
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.07.2011, 23:47     Перевод символа в Юникод
Еще ссылки по теме:

Юникод символ в консоли C++
Вывод юникод символа в консоль C++
Юникод в двоичную систему C++

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

Или воспользуйтесь поиском по форуму:
schdub
 Аватар для schdub
2902 / 1246 / 222
Регистрация: 19.01.2009
Сообщений: 3,210
Завершенные тесты: 1
05.07.2011, 23:47     Перевод символа в Юникод #20
Цитата Сообщение от Danvern Посмотреть сообщение
C
1
for(int i = 0;i < (int)strlen(s);i++)
вопрос на засыпку, как Вы думаете сколько раз будет вызвана функция strlen() ?

Пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
int counter()
{
    static int r = 0;
    std::cout << r++ << std::endl;
    return 10;
}
 
int main()
{
    for (int i = 0; i < counter(); ++i)
    {
        ;
    }
    system("pause");
    return 0;
}
Добавлено через 1 минуту
Цитата Сообщение от grizlik78 Посмотреть сообщение
так как у меня, например, sizeof(wchar_t) == 4
grizlik78, естественно, я говорил о своем компиляторе
Yandex
Объявления
05.07.2011, 23:47     Перевод символа в Юникод
Ответ Создать тему
Опции темы

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