Написать функцию, которая конвертирует строку (char*), содержащую число в шестнадцатеричном представлении (HEX) в число (int), то есть реализацию atoi для чисел в шестнадцатеричной системе счисления. Прототип функции:
int hex_atoi(const char* hex_string);
Условия:
0. Язык программирования — С/С++.
1. Запрещается пользоваться любыми библиотечными функциями (типа strlen и пр.), а также сторонними классами и иже с ними. В двух словах, задача должна решаться встроенными средствами языка С/С++.
2. Пробельные символы в начале строки (пробел и символ табуляции — \t) опускаются.
3. Знак числа должен сохраняться.
4. Возвращаемое значение — либо 0 в случае ошибки, либо часть числа до момента встречи ошибки (например, если строка содержит значение "0xA0jFD", то возвращаемым значением будет число 160
5. Передаваемая строка содержит числа в шестнадцатеричном формате.
6. Переполнение учитывается (например, вызов hex_atoi("0xFFFFFFFF") выдаст число -1 ).
7. Допускается опускание в строке указания системы счисления (то есть, строки "0xBF" и "BF" идентичны).
8. Запрещается использовать операторы continue и goto в цикле.
9. Количество вспомогательных переменных ограничено тремя.
10. Использование конструкции switch, а также цикла do...while (но не while - его можно) запрещается.
Здравствуйте Flamer, Вы писали:
F>Итак, задача номер два (посложнее ;) ):
F>Условия:
F>3. Знак числа должен сохраняться.
Гекс со знаком — оу е!
F>4. Возвращаемое значение — либо 0 в случае ошибки, либо часть числа до момента встречи ошибки (например, если строка содержит значение "0xA0jFD", то возвращаемым значением будет число 160
Халява сэр
F>6. Переполнение учитывается (например, вызов hex_atoi("0xFFFFFFFF") выдаст число -1 ).
А "0x123456789" = 0x12345678 или 0x23456789 ?
F>7. Допускается опускание в строке указания системы счисления (то есть, строки "0xBF" и "BF" идентичны).
F>8. Запрещается использовать операторы continue и goto в цикле. F>10. Использование конструкции switch, а также цикла do...while (но не while - его можно) запрещается.
Любим усложнять жизнь?
int hexatoi(const char* str)
{
if(!str) return 0;
int v = 0; // аккумуляторbool n = false; // негативchar c = *(str++); // пригодится
// ожидаем пробелыwhile(c == ' ' || c == '\t') c = *(str++);
if(!c) return 0;
// ожидаем знак
// на мой взгляд, так эффективнее, чем громоздить n = (...) ? (...) : (...)if(c == '-') { n = true; c = *(str++); }
else if(c == '+') c = *(str++);
if(!c) return 0; // В принципе, эту проверку можно опустить. Но она быстрая, облегчит жизнь маломало
// ожидаем префикс
// а если это просто 0, то и бог с ним. Не жалкоif(
c == '0' &&
(((c = *(str++)) == 'x') || (c == 'X'))
) c = *(str++);
// ожидаем цифры
// кто не верит оптимизатору, пусть напишет 55 вместо 'A'-10...while(
(с >= '0' && c <= 'f') && // оптимизирующая проверка - для быстрого отсечения неправильных символов
( // повторные проверки c>='0',c<='f' оставлены "для наглядности" (или если убрать оптимизирующую)
(c >= '0' && c <= '9') && (v <<= 4, v += (c - '0' ), true) ||
(c >= 'A' && c <= 'F') && (v <<= 4, v += (c - ('A' - 10)), true) ||
(c >= 'a' && c <= 'f') && (v <<= 4, v += (c - ('a' - 10)), true)
)
) c = *(str++);
return n ? -v : v;
}
Здравствуйте Flamer, Вы писали:
F>Итак, задача номер два (посложнее ):
Вопросик можно А чем она посложнее ? Ну у числа другое основание и все тут.
Для Oct было бы не 16 или 10, а 8. И просто ограничения на символы от 0 до 7.
Здравствуйте Vampire, Вы писали:
V>Здравствуйте Flamer, Вы писали:
F>>Итак, задача номер два (посложнее ):
V>Вопросик можно А чем она посложнее ? Ну у числа другое основание и все тут. V>Для Oct было бы не 16 или 10, а 8. И просто ограничения на символы от 0 до 7. V>
Ну так посложнее же Пусть немножко, но все-же... Обороты надо набирать постепенно
Здравствуйте Flamer, Вы писали:
F>Здравствуйте Vampire, Вы писали:
V>>Здравствуйте Flamer, Вы писали:
F>>>Итак, задача номер два (посложнее ):
V>>Вопросик можно А чем она посложнее ? Ну у числа другое основание и все тут. V>>Для Oct было бы не 16 или 10, а 8. И просто ограничения на символы от 0 до 7. V>>
F>Ну так посложнее же Пусть немножко, но все-же... Обороты надо набирать постепенно
Ну тогда вот чисто мат. задачка.
Конвертор чисел по любому основанию.
Это значит не только 2 8 10 16, но и любое другое типа 12 и т.п.
Здравствуйте Flamer, Вы писали:
F>Итак, задача номер два (посложнее ):
F>Задача:
F>Написать функцию, которая конвертирует строку (char*), содержащую число в шестнадцатеричном представлении (HEX) в число (int), то есть реализацию atoi для чисел в шестнадцатеричной системе счисления. Прототип функции: F>Условия: F>0. Язык программирования — С/С++. F>1. Запрещается пользоваться любыми библиотечными функциями (типа strlen и пр.), а также сторонними классами и иже с ними. В двух словах, задача должна решаться встроенными средствами языка С/С++. F>2. Пробельные символы в начале строки (пробел и символ табуляции — \t) опускаются. F>3. Знак числа должен сохраняться. F>4. Возвращаемое значение — либо 0 в случае ошибки, либо часть числа до момента встречи ошибки (например, если строка содержит значение "0xA0jFD", то возвращаемым значением будет число 160 F>5. Передаваемая строка содержит числа в шестнадцатеричном формате. F>6. Переполнение учитывается (например, вызов hex_atoi("0xFFFFFFFF") выдаст число -1 ). F>7. Допускается опускание в строке указания системы счисления (то есть, строки "0xBF" и "BF" идентичны). F>8. Запрещается использовать операторы continue и goto в цикле. F>9. Количество вспомогательных переменных ограничено тремя. F>10. Использование конструкции switch, а также цикла do...while (но не while - его можно) запрещается.
почему бы не написать сразу универсальную функцию определяюшюю тип числа по началу записи
0x — HEX
0 — OCT
остальное DEC
соответственно проверяя коректность символов (т.е 0xa => 10, а 0a => 0, a => 0)
условия оставим теже, но немного довавим
1. сделать две функции
а. signed long sig_uni_atoi(const char *str);
учитывеет знак, знаковый бит. при переролнении возврашает 0, (т.е 2147483648 => 0)
б. unsigned long usig_uni_atoi(const char *str);
не учитывеет знак, знаковый бит.
(можно дополнить/исправить)
Не проверял, мог и напутать где-нить, со скобками например
Хотя с if-ами нагляднее конечно, только поставьте else, ибо условия взаимоисключающие, а оптимизациям компилера тут как-то не верят
Блин, только что проснулся, т.к. как раз понадобилась такая весчь для одной маленькой библиотечки, где, по условию задачи, 30 Кб CRT-runtime тащить низзя... Долго вкуривал в выделенные жирным строчки... И пришел к выводу — браво, маэстро!
К>
[]
К> ( // повторные проверки c>='0',c<='f' оставлены "для наглядности"
// (или если убрать оптимизирующую)К> (c >= '0' && c <= '9') && (v <<= 4, v += (c - '0' ), true) ||
К> (c >= 'A' && c <= 'F') && (v <<= 4, v += (c - ('A' - 10)), true) ||
К> (c >= 'a' && c <= 'f') && (v <<= 4, v += (c - ('a' - 10)), true)
К> )
К> ) c = *(str++);
К> return n ? -v : v;
К>}
К>
Здравствуйте, Flamer, Вы писали:
F>Здравствуйте, Кодт, Вы писали:
F>[]
F>Блин, только что проснулся, т.к. как раз понадобилась такая весчь для одной маленькой библиотечки, где, по условию задачи, 30 Кб CRT-runtime тащить низзя... Долго вкуривал в выделенные жирным строчки... И пришел к выводу — браво, маэстро!
Здравствуйте, Flamer, Вы писали:
F>Блин, только что проснулся, т.к. как раз понадобилась такая весчь для одной маленькой библиотечки, где, по условию задачи, 30 Кб CRT-runtime тащить низзя... Долго вкуривал в выделенные жирным строчки... И пришел к выводу — браво, маэстро!
Год спал, ещё год курил?
Ты ж сам задачу поставил, в августе 2002...
Здравствуйте, MaximE, Вы писали:
ME>Chez wrote:
ME>А чем strtol не устраивает?
Это не то 1) если префикса 0x нет — рассматривает число как десятичное
5. Передаваемая строка содержит числа в шестнадцатеричном формате.
2) возвращает другие результаты в случае ошибок, а надо:
4. Возвращаемое значение — либо 0 в случае ошибки, либо часть числа до момента встречи ошибки (например, если строка содержит значение "0xA0jFD", то возвращаемым значением будет число 160
3) но самое главное, что задание было поставлено просто как разминка для мозгов !
1. Запрещается пользоваться любыми библиотечными функциями (типа strlen и пр.), а также сторонними классами и иже с ними. В двух словах, задача должна решаться встроенными средствами языка С/С++.
...
8. Запрещается использовать операторы continue и goto в цикле.
9. Количество вспомогательных переменных ограничено тремя.
10. Использование конструкции switch, а также цикла do...while (но не while — его можно) запрещается.