3

私が書いたプログラムは、単一の 16 進数値のみで構成される人口統計で機能します。(おそらく最も洗練されたソリューションではありませんが、私は新しいプログラマーです) 私の質問は、0xAF や 0xFF などの複数の 16 進数をどのように処理すればよいかということです。正確にはわかりませんが、試行錯誤しているように見えました。誰かに私の手を握ってほしいと言っているわけではありませんが、このコードで間違っていた箇所と、それを修正する方法についての考えを教えてください。

ありがとう :)

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

私は 1 つのループを選び、実装を再考するためにあなたに任せます。具体的にはこれ:

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

あなたがおそらく思っていることをしません...

  • isdigit()TRUEである文字の最初のスパンのみを処理します。
  • isdigit()FALSEの最初の文字で停止します。
  • isdigit('\0')は FALSE であることがわかっているため、最後まで実行されません。しかし、それが偶然正しいかもしれないと心配しています。
  • 0 ~ 9 の数字だけで表現できる 16 進数を正しく変換します。

プログラム全体で考慮すべき事項:

  • 一般に、変更が重要な副作用でない限り、入力文字列を変更しないことをお勧めします。サンプルコードでは、文字列を強制的に小文字にしています。入力文字列をその場で変更することは、ユーザーの書き込みが未定義の動作htoi("1234")を呼び出していることを意味します。あなたは本当にそれをしたくありません。
  • 数字のループの 1 つだけが、ゼロ以外の数字を処理します。
  • に送信0123456789ABCDEF0123456789ABCDEFするとどうなりstdinますか?
  • あなたは何を得ると思います80000000か?何を手に入れましたか?びっくりした?
  • 個人的にはNLforは使いません'\n'。C の使用法は、マクロが便利ではない多くのコンテキストで見られることをほとんど期待して\nいるので、今は慣れた方がよいでしょう...
于 2009-04-30T06:25:08.043 に答える
1

誰かがすでにこれを尋ねています (hex to int、k&r 2.3)。良い答えがたくさんありますが、空白を埋める必要があります。

16 進数から 10 進数への変換 [K&R 演習]

編集:

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

\0 は必要ありません。16 進数はすでにヌルで終了しています。長さは len (0...f) + 1 = 17 バイトです。

于 2009-04-30T01:48:29.313 に答える
0

これは、複数の 16 進数の値を 10 進数の整数に変換するための従来の 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 に答える
0

文字列の最大サイズは、24 ではなく 10 か 18 のいずれかにする必要があるとint思います。

10 : int は通常 4 バイトをhtoi()返すためint(システムも確認してください)、16 進数の長さは最大で 8 桁 (4 ビットから 1 16 桁、8 ビットから 1 バイト) になる可能性があり、オプション0xまたは0X.

18 : htoi()a とその 8 バイトが返された方がよいでしょうlong(再度、システムを確認してください)。そのため、16 進数の長さは最大 16 桁であり、オプションの0xorを許可したいと考えています0X

intとのサイズはマシンに依存することに注意してくださいlong。それらを見つけるには、K&R ブックの演習 2.1 を参照してください。

于 2013-08-17T03:34:26.227 に答える