3

The program I wrote works in demographics consisting of only single Hexadecimal values. (Probably not the most elegant solution, but I'm a new programmer) My question is, how would I go about handling of multiple hexadecimal digits, such as 0xAF, or 0xFF, etc? I'm not exactly sure, and I've seemed confuse myself greatly, in the attempt. I'm not asking for someone to hold my hand, but to give me a tip where I've gone wrong in this code and thoughts on how to fix it.

Thanks :)

/* 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

4 回答 4

1

我将选择一个循环,并让您重新考虑您的实现。具体来说:

for(i = 0; isdigit(hexd[i]); i++)
    n = (16 * i) + (hexd[i] - '0');

没有做你可能认为它会做的事情......

  • 它只处理第一个isdigit()为 TRUE 的字符范围。
  • 它在第一个isdigit()为 FALSE 的字符处停止。
  • 它不会超过结尾,因为isdigit('\0')已知为 FALSE。不过,我担心这可能会意外正确。
  • 它确实正确转换了只​​能用数字 0-9 表示的十六进制数。

整个程序要考虑的事情:

  • 一般来说,最好不要修改输入字符串,除非修改是有价值的副作用。在您的示例代码中,您正在强制字符串就地小写。就地修改输入字符串意味着用户htoi("1234")正在调用未定义的行为。你真的不想那样做。
  • 只有一个数字循环将处理非零位数。
  • 如果我发送0123456789ABCDEF0123456789ABCDEF到会发生什么stdin
  • 你期望得到80000000什么?你得到了什么?你惊喜吗?
  • 就个人而言,我不会使用NLfor '\n'。C 的用法几乎希望\n在很多不方便使用宏的上下文中看到,所以最好现在就习惯它......
于 2009-04-30T06:25:08.043 回答
1

Someone has alredy asked this (hex to int, k&r 2.3). Take a look, there are many good answers, but you have to fill in the blanks.

Hex to Decimal conversion [K&R exercise]

Edit:

in

char hex[] = "0123456789ABCDEFabcdef\0";

The \0 is not necesary. hex is alredy nul terminated. Is len (0...f) + 1 = 17 bytes long.

于 2009-04-30T01:48:29.313 回答
0

我认为字符串的 MAX 大小应该是 10 或 18 而不是 24。(如果你已经int在你的机器上检查过并遵循下面的推理,将它作为注释包含在你的代码中会很有好处。)

10:因为htoi()返回一个int,int通常是4个字节(检查你的系统也是),所以十六进制数的长度最多可以是8位(4位到1个十六进制位,8位到一个字节),我们希望允许可选0x0X

htoi()18 :如果返回 a和它的 8 个字节会更好long(再次检查你的系统),所以十六进制数的长度最多可以是 16 位,我们希望允许可选的0xor 0X

请注意intlong的大小取决于机器,请查看 K&R 书中的练习 2.1 以找到它们。

于 2013-08-17T03:34:26.227 回答
0

这是我的经典 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';
}
于 2015-07-27T20:38:32.770 回答