K&R Exercise 2-3 "Hex to int converter" Problem
Программа, которую я написал, работает в демографии, состоящей только из одного шестнадцатеричного значения. (Возможно, это не самое элегантное решение, но я новый программист). Мой вопрос: как мне поступить с обработкой нескольких шестнадцатеричных цифр, таких как 0xAF или 0xFF, и т. Д.? Я не совсем уверен, и я, похоже, сильно запутался в этой попытке. Я не прошу, чтобы кто-то держал меня за руку, но чтобы дать мне подсказку, где я ошибся в этом коде, и размышления о том, как это исправить.
Спасибо:)
/* Exercise 2-3. Write the function htoi(s), which converts a string of
* hexadecimal digits (including an optional 0x or 0X) into it's equivalent
* integer value. The allowable digits are 0...9 - A...F and a...f.
*
*/
#include <stdio.h>
#include <string.h>
#define NL '\n'
#define MAX 24
int htoi(char *hexd);
int
main(void)
{
char str[MAX] = {0};
char hex[] = "0123456789ABCDEFabcdef\0";
int c;
int i;
int x = 0;
while((c = getchar()) != EOF) {
for(i = 0; hex[i] != '\0'; i++) {
if(c == hex[i])
str[x++] = c;
}
if(c == NL) {
printf("%d\n", htoi(str));
x = 0, i = x;
}
}
return 0;
}
int
htoi(char *hexd)
{
int i;
int n = 0;
for(i = 0; isdigit(hexd[i]); i++)
n = (16 * i) + (hexd[i] - '0');
for(i = 0; isupper(hexd[i]); i++) /* Let's just deal with lowercase characters */
hexd[i] = hexd[i] + 'a' - 'A';
for(i = 0; islower(hexd[i]); i++) {
hexd[i] = hexd[i] - 'a';
n = (16 + i) + hexd[i] + 10;
n = hexd[i] + 10;
}
return n;
}
4 ответа
Кто-то уже спрашивал об этом (hex to int, k&r 2.3). Посмотрите, есть много хороших ответов, но вы должны заполнить пробелы.
Преобразование шестнадцатеричного в десятичное [упражнение K&R]
Редактировать:
в
char hex[] = "0123456789ABCDEFabcdef\0";
\0 не является необходимым. шестнадцатеричное окончено. Длина len (0...f) + 1 = 17 байт.
Я выберу один цикл и предоставлю вам переосмысление вашей реализации. Конкретно это:
for(i = 0; isdigit(hexd[i]); i++)
n = (16 * i) + (hexd[i] - '0');
не делает то, что вы, вероятно, думаете, что делает...
- Он обрабатывает только первый диапазон символов, где
isdigit()
правда. - Останавливается на первом символе, где
isdigit()
ЛОЖЬ. - Это не проходит мимо конца, потому что
isdigit('\0')
как известно, ЛОЖЬ. Я обеспокоен тем, что это может быть случайно правильно, хотя. - Он правильно конвертирует шестнадцатеричное число, которое может быть выражено исключительно цифрами 0-9.
Что нужно продумать для всей программы:
- Как правило, предпочитайте не изменять входные строки, если изменение не является ценным побочным эффектом. В вашем примере кода вы заставляете строку вводиться в нижнем регистре. Изменение входной строки на месте означает, что пользователь пишет
htoi("1234")
вызывает неопределенное поведение. Вы действительно не хотите этого делать. - Только один из циклов над цифрами будет обрабатывать ненулевое число цифр.
- Что произойдет, если я отправлю
0123456789ABCDEF0123456789ABCDEF
вstdin
? - Что вы ожидаете получить за
80000000
? Что ты получил? Вы удивлены? - Лично я бы не использовал
NL
за'\n'
, Использование C в значительной степени ожидает увидеть\n
во многих случаях, когда макрос не удобен, лучше просто привыкнуть к нему сейчас...
Я думаю, что максимальный размер строки должен быть 10 или 18 вместо 24 (если вы уже проверили int
на вашем компьютере и следуя приведенным ниже рассуждениям, было бы полезно включить его в качестве комментария в ваш код.)
10: с htoi()
возвращает int
, int обычно составляет 4 байта (проверьте и вашу систему), поэтому шестнадцатеричное число может быть длиной не более 8 цифр (от 4 бит до 1 шестнадцатеричной цифры, 8 бит до байта), и мы хотим разрешить дополнительный 0x
или же 0X
,
18: было бы лучше, если htoi()
вернул long
и его 8 байтов (опять же, проверьте вашу систему), так что шестнадцатеричное число может быть длиной не более 16 цифр, и мы хотим, чтобы для дополнительного 0x
или же 0X
,
Обратите внимание, что эти размеры int
а также long
зависят от машины, и, пожалуйста, посмотрите упражнение 2.1 в книге K&R, чтобы найти их.
Вот моя версия классической функции htoi() для преобразования нескольких шестнадцатеричных значений в десятичные целые числа. Это полноценная рабочая программа, скомпилируйте ее и запустите.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int htoi(const char*);
int getRawInt(char);
int main(int argc, char **argv) {
char hex[] = " ";
printf("Enter a hexadecimal number (i.e 33A)\n");
scanf("%s", hex);
printf("Hexedecimal %s in decimal is %d\n", hex, htoi(hex)); // result will be 826
return 0;
}
int htoi(const char *hex) {
const int LEN = strlen(hex) -1;
int power = 1;
int dec = 0;
for(int i = LEN; i >= 0; --i) {
dec += getRawInt(hex[i]) * power;
power *= 16;
}
return dec;
}
int getRawInt(char c) {
if(isalpha(c)) {
return toupper(c) - 'A' + 10;
} return c-'0';
}