这个将十六进制数(作为字符传递)转换为无符号数的函数有什么错误?怎么解决呢?

问题描述 投票:0回答:1

我一直在阅读 Jens Gustedt 所著的 Modern C 书以及第 8.4 节,其中介绍了处理字符串处理和转换的 C 库函数,其中有一段代码定义了一个函数它将表示十六进制 (36) 基数的单个 char(使用其 int 值)转换为其十进制等效值。这个函数应该解释 <stdlib.h> 的 strtoul 函数的一部分是如何工作的。

这是提供的代码:

/* Supposes that lowercase characters are contiguous. */
static_assert('z'-'a' == 25,
                "alphabetic characters not contiguous");
#include <ctype.h>
/* Converts an alphanumeric digit to an unsigned */
/* '0' ... '9'  =>  0 ..  9u */
/* 'A' ... 'Z'  => 10 .. 35u */
/* 'a' ... 'z'  => 10 .. 35u */
/* Other values =>   Greater */
unsigned hexatridecimal(int a) {
        if (isdigit(a)) {
                /* This is guaranteed to work: decimal digits
                   are consecutive, and isdigit is not
                   locale dependent. */
                return a - '0';
        } else {
                /* Leaves a unchanged if it not lowercase */
                a = toupper(a);
                /* Returns value >= 36 if not Latin uppercase */
                return (isupper(a)) ? 10 + (a - 'A') : -1;
        }
}

问题是,要将字母转换为十进制值,需要使用 (a - 'A'),其中 a 表示要转换的字母。关于这个操作,作者是这样进行的:

  1. 第二个return十六进制a'A'之间的关系做出假设。它是什么?

  2. 描述不满足此假设的错误场景。

  3. 修复此错误:即重写代码,使其不对a'A'之间的关系做出任何假设。

现在,我不知道我是否漏掉了一些关键信息,或者是否遗漏了其他信息,但我无法弄清楚点号 23

对于第一点,我认为假设是 a 大于或等于 'A'。因为这是根据函数上面的注释产生正确值所需要的。问题是,通过在代码开头使用 static_assert 和在 return 行使用 三元运算符,以 isupper(a) 作为条件,我看不到它发生,因此不不知道第二点该争论什么。因此,我也陷入了第三点。

这个假设和我的假设有什么不同吗?这有什么错误,什么时候会导致错误以及如何修复它?

c data-conversion
1个回答
0
投票
    这个断言没有断言任何东西。 'z' - 'a' 可以给出 25 并且字母不会连续。
    想象一下编码:
  • abcde0123456789pqrstuwxyzfghijklmno
    'z' - 'a' == 25
    
    
    我不知道为什么它被称为
  1. hexatridecimal
    ,因为它不限制字符为数字和'ABCDEF`。因此,如果在将 base16 字符串转换为整数的函数中使用它,则会出现不稳定的错误。
© www.soinside.com 2019 - 2024. All rights reserved.