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

Преобразовать хэш-функцию для работы с wchar_t - C++

Восстановить пароль Регистрация
 
Монтгомери
0 / 0 / 0
Регистрация: 10.09.2013
Сообщений: 112
31.03.2016, 09:09     Преобразовать хэш-функцию для работы с wchar_t #1
Надо переделать данную функцию для работы не с const char*, а с const wchar_t*.
C++
1
2
3
4
5
6
7
unsigned int HashLy(const char*str)
{
    unsigned int hash=0;
    for (; *str; str++) 
        hash=(hash*1664525)+(unsigned char)(*str)+1013904223;
    return hash;
}
Но при попытке "в тупую" заменить в коде char на wchar_t в 5 строке компилятор начинает ругаться на (unsigned wchar_t)(*str).
Не могли бы вы объяснить, в чём вообще заключается принцип такой записи: (unsigned char)(*str) и почему она не работает?
И подсказать, как это лучше переделать для работы с wchar_t?
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Olej
 Аватар для Olej
123 / 117 / 13
Регистрация: 25.03.2012
Сообщений: 456
31.03.2016, 12:22     Преобразовать хэш-функцию для работы с wchar_t #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Монтгомери Посмотреть сообщение
Не могли бы вы объяснить, в чём вообще заключается принцип такой записи: (unsigned char)(*str) и почему она не работает?
И подсказать, как это лучше переделать для работы с wchar_t?
1. (unsigned char)(*str) - возвращает вам числовой код символа в диапазоне [0...255]. (signed char)(*str) - возвращал бы вам код в диапазоне [-128...127].
2. ругается потому, что wchar_t - уже определён как беззнаковый
3. я не знаю, откуда вы придумали такую хэш-функцию, но с wchar_t у вас будут проблемы в зависимости от операционной системы: в Linux/POSIX wchar_t - это uint32, а в Windows - это uint16.
Serg_o_Grey
46 / 46 / 19
Регистрация: 29.03.2016
Сообщений: 260
31.03.2016, 12:59     Преобразовать хэш-функцию для работы с wchar_t #3
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
#include <iostream>
 
using namespace std; 
 
template<typename T>
unsigned int HashLy(T* str)
{
    unsigned int hash=0;
    unsigned char *b = (unsigned char*)&str[0];
    int size = sizeof(str[0]);
    for (int i = 0; str[i]; i++)
    {
        b = (unsigned char*)&str[i];
        for (int j=0; j<size; j++)
        {
            hash=(hash*1664525)+(b[j])+1013904223;
        }
    }
    cout << hash << endl;
    return hash;
}
 
int main(int argc, char** argv) 
{
    const char* str1= "sgdgjfjfjsdndfj";
    HashLy(str1);
    const wchar_t* str2= L"sgdgjfjfjsdndfj";
    HashLy(str2);
    
    return 0;
}
Добавлено через 6 минут
Olej, по поводу wchar_t и uint32 . wchar-t - это двухбайтовая переменная в windows и ничего общего с четырехбайтовым UINT не имеет. (полагаю что uint32 тоже четырехбайтная)

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
#include <windows.h>
#include <iostream>
#include <string>
#include <typeinfo>
 
using namespace std;
 
int main(int argc, char** argv)
{
    cout << "ЛОГИЧЕСКИЕ ТИПЫ" << endl;
    cout << "\tbool\t\t\t"<< typeid(bool).name() << endl;
    cout << endl;
    cout << "СИМВОЛЬНЫЕ ТИПЫ" << endl;
    cout << "\t__int8\t\t\t"<< typeid(__int8).name() << endl;
    cout << "\tchar\t\t\t"<< typeid(char).name() << endl;
    cout << "\tTCHAR\t\t\t"<< typeid(TCHAR).name() << endl;
    cout << "\tLPSTR\t\t\t"<< typeid(LPSTR).name() << endl;
    cout << "\tLPTSTR\t\t\t"<< typeid(LPTSTR).name() << endl;
    cout << "\tunsigned char\t\t"<< typeid(unsigned char).name() << endl;
    cout << "\tBYTE\t\t\t"<< typeid(BYTE).name() << endl;
    cout << "\twchar_t\t\t\t"<< typeid(wchar_t).name() << endl;
    cout << "\tLPWSTR\t\t\t"<< typeid(LPWSTR).name() << endl;
    cout << endl;
    cout << "СТРОКОВЫЕ ТИПЫ" << endl;
    cout << "\tstring\t\t\t"<< typeid(string).name() << endl;
    cout << endl;
    cout << "ЦЕЛОЧИСЛЕННЫЕ ТИПЫ" << endl;
    cout << "\t__int16\t\t\t"<< typeid(__int16).name() << endl;
    cout << "\tshort\t\t\t"<< typeid(short).name() << endl;
    cout << "\tunsigned short\t\t"<< typeid(unsigned short).name() << endl;
    cout << "\tWORD\t\t\t"<< typeid(WORD).name() << endl;
    cout << "\t__int32\t\t\t"<< typeid(__int32).name() << endl;
    cout << "\tint\t\t\t"<< typeid(int).name() << endl;
    cout << "\tINT\t\t\t"<< typeid(INT).name() << endl;
    cout << "\tNULL\t\t\t"<< typeid(NULL).name() << endl;
    cout << "\tBOOL\t\t\t"<< typeid(BOOL).name() << endl;
    cout << "\tunsigned int\t\t"<< typeid(unsigned int).name() << endl;
    cout << "\tunsigned int*\t\t"<< typeid(unsigned int*).name() << endl;
    cout << "\tUINT\t\t\t"<< typeid(UINT).name() << endl;
    cout << "\tWPARAM\t\t\t"<< typeid(WPARAM).name() << endl;
    cout << "\tlong\t\t\t"<< typeid(long).name() << endl;
    cout << "\tLONG\t\t\t"<< typeid(LONG).name() << endl;
    cout << "\tLPARAM\t\t\t"<< typeid(LPARAM).name() << endl;
    cout << "\tLRESULT\t\t\t"<< typeid(LRESULT).name() << endl;
    cout << "\t__int64\t\t\t"<< typeid(__int64).name() << endl;
    cout << "\tlong long\t\t"<< typeid(long long).name() << endl;
    cout << "\tunsigned long\t\t"<< typeid(unsigned long).name() << endl;
    cout << "\tDWORD\t\t\t"<< typeid(DWORD).name() << endl;
    cout << "\tunsigned long long\t"<< typeid(unsigned long long).name() << endl;
    cout << endl;
    cout << "ЧИСЛА С ПЛАВАЮЩЕЙ ТОЧКОЙ" << endl;
    cout << "\tfloat\t\t\t"<< typeid(float).name() << endl;
    cout << "\tdouble\t\t\t"<< typeid(double).name() << endl;
    cout << "\tlong double\t\t"<< typeid(long double).name() << endl;
    cout << endl;
    cout << "ДРУГИЕ" << endl;
    cout << "\tLPCSTR\t\t\t"<< typeid(LPCSTR).name() << endl;
    cout << "\tLPCTSTR\t\t\t"<< typeid(LPCTSTR).name() << endl;
    cout << "\tLPCWSTR\t\t\t"<< typeid(LPCWSTR).name() << endl;
    cout << "\tvoid\t\t\t"<< typeid(void).name() << endl;
    return 0;
}
Программа выводит коды типов данных для windows. Переменные WPARAM, LPARAM и LRESULT в разных версиях windows имеют разный код
Olej
 Аватар для Olej
123 / 117 / 13
Регистрация: 25.03.2012
Сообщений: 456
31.03.2016, 13:23     Преобразовать хэш-функцию для работы с wchar_t #4
Цитата Сообщение от Serg_o_Grey Посмотреть сообщение
Olej, по поводу wchar_t и uint32 . wchar-t - это двухбайтовая переменная в windows
А кого вообще должно интересовать что там в Windows?

В Windows wchar_t - это uint16, потому как там и Unicode - это UTF-16
Но во всех нормальных операционных системах wchar_t - это uint32... так точно, 4 байта.

Добавлено через 11 минут
Цитата Сообщение от Монтгомери Посмотреть сообщение
Надо переделать данную функцию для работы не с const char*, а с const wchar_t*.
Если вы в C++ раздел пишее, а не C, то у вас есть тип wstring со своими методами, и будет ... красивше
C++
1
2
unsigned int HashLy( const wstring& str ) {
...
P.S. Только с хэш-функцией для char* вы можете легко нарваться на переполнение unsigned int операций.
avgoor
562 / 352 / 83
Регистрация: 05.12.2015
Сообщений: 1,137
31.03.2016, 13:26     Преобразовать хэш-функцию для работы с wchar_t #5
Цитата Сообщение от Olej Посмотреть сообщение
А кого вообще должно интересовать что там в Windows?
Странный вопрос. Т.к. большую часть не волнует что там в Linux.
Olej
 Аватар для Olej
123 / 117 / 13
Регистрация: 25.03.2012
Сообщений: 456
31.03.2016, 13:40     Преобразовать хэш-функцию для работы с wchar_t #6
Цитата Сообщение от avgoor Посмотреть сообщение
Странный вопрос.
Это не вопрос. Это утверждение

А на C++ нужно писать так, чтобы стремиться к переносимости между представлениями.
А иначе лучше писать на C.
avgoor
562 / 352 / 83
Регистрация: 05.12.2015
Сообщений: 1,137
31.03.2016, 14:02     Преобразовать хэш-функцию для работы с wchar_t #7
Цитата Сообщение от Olej Посмотреть сообщение
Это не вопрос. Это утверждение
Утверждение - это когда в конце предложения стоит '.' или '!'. А когда стоит '?' - это вопрос.
Монтгомери
0 / 0 / 0
Регистрация: 10.09.2013
Сообщений: 112
31.03.2016, 15:24  [ТС]     Преобразовать хэш-функцию для работы с wchar_t #8
Цитата Сообщение от Olej Посмотреть сообщение
2. ругается потому, что wchar_t - уже определён как беззнаковый
Спасибо, (wchar_t)(*str) работает как надо.

Цитата Сообщение от Olej Посмотреть сообщение
3. я не знаю, откуда вы придумали такую хэш-функцию, но с wchar_t у вас будут проблемы в зависимости от операционной системы: в Linux/POSIX wchar_t - это uint32, а в Windows - это uint16.
Взял отсюда:
LY Hash Function
Congruential generator proposed by Leonid Yuriev. Multiplier constant suggested by M.Lavaux & F.Janssens.
Я об этом не говорил, но это нужно для учебной программы в виде .exe-шника, то есть реализация на других платформах действительно не представляет интереса.
Хотя на будущее факт учту, спасибо.
А поскольку преподаватель советовал использовать wstring, то и работать приходится с wchar_t.

Добавлено через 7 минут
Цитата Сообщение от Olej Посмотреть сообщение
А иначе лучше писать на C
В данном случае снова не вариант, в программе будут активно классы использоваться.
Olej
 Аватар для Olej
123 / 117 / 13
Регистрация: 25.03.2012
Сообщений: 456
31.03.2016, 16:16     Преобразовать хэш-функцию для работы с wchar_t #9
Цитата Сообщение от avgoor Посмотреть сообщение
А когда стоит '?' - это вопрос.
Я успокою ваши сомнения: это риторический вопрос.

Добавлено через 2 минуты
Цитата Сообщение от Монтгомери Посмотреть сообщение
А поскольку преподаватель советовал использовать wstring, то и работать приходится с wchar_t.
Преподаватель советовал?
Вот и используйте непосредстенно wstring как класс, тип, контейнер (преподаватель плохого не посоветует).
Зачем вам нужен низкоуровневый wchar_t?
Монтгомери
0 / 0 / 0
Регистрация: 10.09.2013
Сообщений: 112
31.03.2016, 16:57  [ТС]     Преобразовать хэш-функцию для работы с wchar_t #10
Цитата Сообщение от Olej Посмотреть сообщение
Вот и используйте непосредстенно wstring как класс, тип, контейнер (преподаватель плохого не посоветует).
Зачем вам нужен низкоуровневый wchar_t?
Просто я не видел между ними принципиальной разницы, ведь вроде как wstring определён как массив wchar_t.

А разница, как я понимаю, имеется, да?
TheCalligrapher
С чаем беда...
Эксперт С++
 Аватар для TheCalligrapher
2899 / 1435 / 395
Регистрация: 18.10.2014
Сообщений: 2,643
31.03.2016, 17:49     Преобразовать хэш-функцию для работы с wchar_t #11
Цитата Сообщение от Монтгомери Посмотреть сообщение
работать приходится с wchar_t.
Значит, чтобы слегка развеять белиберду, которую вам тут наговорили

1. Ваш функция - это обыкновенная внутренняя функция, призванная генерировать некое хеш-значение для некоей входной строки. Этой функции совершенно все равно, какой размер имеет тип wchar_t - она будет прекрасно работать с любым размером. Никаких проблем ни на Linux, ни на Windows у вас от этого не будет и быть не может в принципе. Подобные заявления - это какой-то притянутый за уши сюр.

2. Заявление об опасности "переполнения unsigned int" - это какая-то белиберда. Ваша функция, как и большинство таких функций, именно фундаментально основана на стандартном поведении переполняющегося типа unsigned int. Т.е. она и должна переполнять unsigned int - для того эта функция и написана.

3. Windows интересует всех. Windows - основная платформа разработки для всех целевых существующих платформ. Например, подавляющее большинство разработки для Linux в мире делается именно под Windows. Поэтому даже ориентируя свой код на Linux, вам придется обеспечить его работоспособность и под Windows. Но с этим в этом коде проблем нет, см. п.1.
Olej
 Аватар для Olej
123 / 117 / 13
Регистрация: 25.03.2012
Сообщений: 456
31.03.2016, 17:58     Преобразовать хэш-функцию для работы с wchar_t #12
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
подавляющее большинство разработки для Linux в мире делается именно под Windows
Это какое же "большинство"?
Огласите весь список, пжалуйста?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.03.2016, 18:13     Преобразовать хэш-функцию для работы с wchar_t
Еще ссылки по теме:

C++ Преобразовать string в wchar_t
C++ Почему const wchar_t* воспринимается как wchar_t* ?
C++ Error C2664: невозможно преобразовать из "wchar_t" в "const wchar_t *"

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

Или воспользуйтесь поиском по форуму:
TheCalligrapher
31.03.2016, 18:13     Преобразовать хэш-функцию для работы с wchar_t
  #13

Не по теме:

Цитата Сообщение от Olej Посмотреть сообщение
Это какое же "большинство"?
Troll alert!

Yandex
Объявления
31.03.2016, 18:13     Преобразовать хэш-функцию для работы с wchar_t
Ответ Создать тему
Опции темы

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