微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 C 中仅使用 write() 函数输出十六进制字符?

如何解决如何在 C 中仅使用 write() 函数输出十六进制字符?

是否有可能在 write() 函数中放入 "%X" 以获得十六进制数的 ascii 字符?

就像 printf("Hex number of .. : %X").

先谢谢你!

解决方法

是否有可能在 write() 函数中放入 "%X" 以获得十六进制数的 ascii 字符?

没有。 %X格式化 输出函数的 printf 系列的特定特征。 ('f' 是“格式化”的助记符。)write() 执行原始输出——正是您指定的字节。如果您想使用 write(),那么您必须自己执行格式化,我认为这是作业重点的很大一部分。

,

简答

由于 write 不接受格式字符串和其他参数,因此您必须使用 printf,或者实现您自己的函数,该函数接受一个整数并将其转换为十六进制表示。

下面我将描述如何编写您自己的类似 %X 的输出以及它是如何工作的。

将字符转换为十六进制字符

通过将数字除以 16 并重复取模,您可以将整数(以及字符的十六进制代码)转换为十六进制字符串。

例如,让我们考虑 'A' 的值,它是 41 的十六进制。该数字除以 16 的余数等于其最后一位数字的值 -- 1。然后,如果我们将值 0x41 除以 16,我们会得到相同的数字,但没有最后一位——0x4

可以想到这样迭代的一个步骤:

int valueToConvert = 'A';
int lastHexDigit = valueToConvert % 16; // get the value of the last hex digit
valueToConvert = valueToConvert / 16;   // save the remainder of the number

这让我们得到最后一个十六进制数字的值(作为整数)。

现在我们要将这个数字的整数值转换为char,即将值0转换为'0'。由于 ASCII 中的字符是连续存储的,我们可以通过将 '0' 添加到我们要转换的整数值来获得数字的值。

char charDigit = '0' + digitValue;

上面的代码片段仅适用于小于或等于 digitValue9。对于数字 AF,我们需要添加一个条件,如果 digitValue 大于 9,我们将(使用相同的逻辑)减去 {{1} } 从 digitValue ,然后添加 10 到它。由于字母字符在 ASCII 代码中也是连续的,我们可以自由地使用 'A' 作为 digitValue-10 字符的偏移量。

'A'

所以如果 char charDigit; if (digitValue < 10) { charDigit = '0' + digitValue; } else { charDigit = 'A' + (digitValue-10); } 是 0xA (10),那么 digitValuedigitValue-10,将 0 添加到 0 只会让我们得到 {{1} }.

将整数转换为十六进制字符串表示

通过对除以 16 取模,我们得到最不重要(最右边)的十六进制数字。但是打印字符串是从左到右,而不是从右到左。

因此,为了打印字符串表示,我们需要某种缓冲区来存储我们最右边的所有字符。请记住这一点——任何 'A' 值都不会超过 8 个十六进制数字,因此我们可以自由分配 8 个字符的数组。

'A'

int 将跟踪我们写入的数组槽。请注意,它设置为 char digits[8]; int digitIndex = 8; ,而不是 digitIndex,这是我稍后解释的原因。

现在让我们放回之前的代码——我们将使用 8 来“将最后一位数字放入数组的最后一个位置,直到余数为零”。

7

假设 do/while 不是负数,这应该产生对应于给定 int valueToConvert = ...; // leaving the declaration here for clarity do { // Get the value of the last digit int lastDigit = valueToConvert % 16; // Convert the last digit to char char charDigit; if (lastDigit < 10) { charDigit = '0' + lastDigit; } else { charDigit = 'A' + (lastDigit-10); } // Put the last digit into the array digitIndex -= 1; digits[digitIndex] = charDigit; valueToConvert /= 16; } while(valueToConvert != 0); 的十六进制值。

现在让我解释为什么我要先减去索引:我们将使用 int 的值(它是一个 valueToConvert)作为我们的数字数组的起点。如果我先减去然后把数字放在那个位置,那保证当循环退出时,digits+digitIndex超过第一个数字,非常方便。

现在让我们得到数组的长度:

char *

这只是缓冲区的大小减去数组中数字第一位的索引。

终于

将值转换为我们的数字数组后,我们只需调用 digitIndex

unsigned count = 8 - digitIndex;

全图:

write
,

您需要编写自己的函数。

char toHexDigit(int x)
{
    char result;
    if(x > 15) x = 0;
    if((x >= 0 && x < 10)) result = '0' + x;
    else result = 'A' + x - 10;

    return result;
}

char *tohex(unsigned x)
{
    static char buff[sizeof(x)*2];

    for(ssize_t i = 0; i < sizeof(x) * 2; i++)
    {
        int shift = (sizeof(x) * 2 - i - 1) * 4;
        buff[i] = toHexDigit((x & (0xf << shift)) >> shift);
    }
    return buff;
}

int main(void)
{
    write(1,tohex(0xD2A45678),sizeof(unsigned)*2);
}

https://godbolt.org/z/zveYazchj

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。