减少存储在字符串中的十六进制值

时间:2019-05-26 18:27:41

标签: c

假设我有:

char str[]="0x7fffffffe181"

基本上我想将十六进制减小到0x7fffffffe180

我该怎么做?

注意:如果最终字符是字母,例如减后的c,则应为b

3 个答案:

答案 0 :(得分:1)

您可以将其转换为整数然后像这样返回:

char *str2;
unsigned long long int len, a = strtoull(str, NULL, 16);
a--;
len = snprintf(NULL, 0, "0x%llx", a);
str2 = malloc(len+1);
sprintf(str2, "0x%llx", a);

答案 1 :(得分:0)

它只能在无符号长long范围内工作。

const char *eptr;
unsigned long long numeric = strtoull(str, &eptr, 16);
if (eptr == str || numeric == 0) {
    /* handle error */
}
sprintf(str, "0x%llx", numeric - 1);

我们不能对有符号的十六进制执行此操作,因为递减0或某些负数会使字符串变长。

从理论上讲,0应该适合strtoull的第三个参数,但是现在它在我们的libc中存在错误,因此不是。

答案 2 :(得分:0)

可以使用铅笔和纸的字符减法方法。

#include <stdio.h>
#include <string.h>

int main ( void) {
    char *digits = "0123456789abcdef";
    char value[] = "0x7fffffffe181";
    char *each = value;
    char *index = value;

    printf ( "%s\n", value);

    while ( *each) { // iterate to end of string
        each++;
    }
    each--; // move from terminating zero to last character
    if ( ( index = strchr ( digits, *each))) { // valid digit
        while ( each > value && index == digits) { // digit is zero
            *each = 'f';
            if ( each > value) {
                each--; // go to leading character
            }
            index = strchr ( digits, *each); // check again for zero
        }
        if ( index && each >= value) { // valid digit and not at first character
            *each = *(index - 1); // minus one
        }
        else {
            strcpy ( value, "negative");
        }
    }

    printf ( "%s\n", value);

    return 0;
}