Главная » Статьи » Программирование » С++ |
В первой версии этой программы были при жесткой проверке обнаружены серьезные баги:
1. в функции выбора профессии при вводе вместо числового значения символа, программа зацикливалась (бесконечное колличество раз совершала одну и ту же операцию) 2. не могла правильно определить совпадение профессии при отличиях в регистрах букв("бухгалтер" и "Бухгалтер" были для нее совершенно разными словами) _______________
1. Первая проблемма не составила для меня какого-нибудь затруднения. Я решил ее за несколько минут. Для этого мне просто понадобилось немного изменить функцию change_oklad. Вот новая реализация этой функции: void change_oklad(Employer sotrudnik[], const int& counter) do vivod_vseh(sotrudnik, counter); cout << endl << "Введите порядковый номер сотрудника: "; // Защита от дурака cout << "Введите новый размер оклада сотрудника: "; sotrudnik[number - 1].new_oklad(newoklad); ans = get_ans(); Основное отличие состоит в том, что пользователь теперь вроизводит ввод данных не в числовую переменную непосредственно, а в переменную типа string. Затем программа берет первый символ из этой строки (а нумерация списка не может быть выше 4-х элементов, следовательно большее колличество символов пользователь вряд-ли будет сознательно вводить) и преобразует его в числовое значение при помощи функции atoi(*char ). Нужно заметить, что передается именно адрес символа, поскольку изначально функция предназначена для работы с символьными массивами. Аналогичный код я вставил и в систему защиты от дурака. 2. Вторая проблема оказалась не столько сложной, сколько кропотливой. Дело в том, что для правильного сравнения двух переменных типа string, нужно, чтобы у них были одинаковые регистры букв (все буквы либо большие заглавные, либо обычные маленькие). В С++ есть стандартная функция подобного преобразования, однако, она работает только для латинских символов. Мне пришлось составлять собственную функцию, которую я назвал melkie_literi. И здесь я столкнулся с основной проблемой. 0 @ 64 А 128 └ 192 В этой таблице отображены символы и соответствующие им значения индексов. Здесь я встретил первую проблему. Латинские символы идут подряд, т.е. их порядок ничем не прерывается. Это значет, что абсолютно любой английский символ можно преобразовать в большой или маленький, посто прибав или отняв определенное значение. С кириллицей все оказалось не так просто! Дело в том, что после маленькой буквы 'п'идет куча какой-то херни, и только через 49 символов ряд русских символов продолжается. Причиной оказалось то, что вся эта таблица хранится в отрицательных значениях! (Хотел бы я посмотреть в глаза тому дебилу, который придумал сделать это именно так!) У символа "А" был индекс -128 вместо 128, а символ "Я" имел индекс -17 вместо 239 (ну бля дибилы так токо могли сделать). Я пол часа поломал голову над новой проблемой, чуть-чуть преобразовал изначальный алгоритм и получил вот что: string Employer::melkie_literi(string insert) return insert; Как вы догадались, функцию melkie_literi я зафигачил в класс Employer, причем в закрытую часть private, поскольку она используется только внутри класса. Следовательно, я изменил и сам класс. Вот его новое определение: class Employer ~Employer(){}; bool find_prof(const string& prof); void new_oklad(const double& newoklad);
friend ostream& operator << (ostream& outs, const Employer& human); private: string melkie_literi(string insert); Алгоритм отлично работал, и единственное, что мне оставалось доделать - преобразовать под новый код функцию find_prof. Вот она (кстати, тоже принадлежит классу Employer: bool Employer::find_prof(const string& prof) функция сравнивает не исходные string'и, а преобразованные, у которых одинаковый регистр всех букв. Преобразованный код программы можно скачать тут:
Скомпилированную программу можно скачать тут:
Обсуждение на форуме:
С уважением, ваш A.Kuznetsov | |
Просмотров: 4557 | Комментарии: 3 | |
Всего комментариев: 3 | ||||||||||
| ||||||||||