【问题标题】:Convert string of hexadecimal to decimal in c在c中将十六进制字符串转换为十进制
【发布时间】:2016-03-06 21:46:23
【问题描述】:

我正在用 C 和汇编编写操作系统,在实现 EXT2 文件系统时遇到了问题。我需要在 c 中将四个字节的十六进制转换为十进制。一个例子是将00 00 01(10000) 转换为65536。我需要转换为十进制,因为解析超级块需要所有值都是十进制的。最具体地说,我正在研究的 ext2 fs 在这里:

#include "ext2.h"
#include <stdlib.h>
long hex2dec(unsigned const char *hex){
long ret = 0;
int i = 0;
while(hex[i] != 0){
    //if(hex[i] >= 0x00 && hex[i] <= 0x09)
    //  ret+=(10 * i) * hex[i];
}
//kprintf("\n");
return ret;
}
char *strsep(char *buf,int offset,int num){
char *ret = malloc(1024);
int j = 0;
int i = offset;
int end = (offset + num);
int i1 = 0;
while(i1 < num){
    ///kstrcat(ret,&buf[i]);
    ret[i1] = buf[i];
    i++;
    i1++;
}
return ret;
}
int get_partition(partnum){
if(partnum > 4)
    return -1;
//int i = (12 * partnum);
int i = 0;
if(partnum == 1)
    i = 190;
else if(partnum == 2)
    i = 206;
else if(partnum == 3)
    i = 222;
else
    i = 190;
int ret = 0;
char *buf = malloc(1024);
ata_read_master(buf,1,0x00);
ret = buf[(i + 2)];
return ret;
}
int _intlen(int i){
int ret = 0;
while(i){
    ret++;
    i/=10;
}
return ret;
}
int _hex2int(char c){
if(c == '0')
    return 0;
else if(c == '1')
    return 1;
else if(c == '2')
    return 2;
else if(c == '3')
    return 3;
    else if(c == '4')
            return 4;
    else if(c == '5')
            return 5;
    else if(c == '6')
            return 6;
    else if(c == '7')
            return 7;
    else if(c == '8')
            return 8;
    else if(c == '9')
            return 9;
    else if(c == 'A')
            return 10;
    else if(c == 'B')
            return 11;
    else if(c == 'C')
            return 12;
    else if(c == 'D')
            return 13;
    else if(c == 'E')
            return 14;
    else if(c == 'F')
            return 15;


}
int hex2int(char c){
int i = c;

}
int comb(const char *str,int n){
int i = 0;
int ret = 0;
while(i < n){
    //if(str[i] == 0x01)
    //  kprintf("(:");
    /*int j = str[i];
    int k = 0;
    int m = 0;
    if(j < 10)
        j*=10;
    else
        while(j > 0){
            k+=(10 ^ (_intlen(j) - m)) * j % 10;
            m++;
            j/=10;
        }
    //kprintf("%d",j);
    //if(j == 1)
    //  kprintf("(:");*/
    i++;
}

//ret = (char)ret;
ret = (char)str
int ret = 0;
int i = 0;
char *s = malloc(1024);
/*while(i < n){

    //kstrcat(s,&((char*)buf[i]));
    n++;
}*/

return ret;
//kprintf("\n");
//return ret;
}
struct ext2_superblock *parse_sblk(int partnum){
int i = get_partition(partnum);
if(i > 0)
    kprintf("[EXT2_SUPERBLOCK]Found partition!\n");
else
    i = 0;
struct ext2_superblock *ret;
struct ext2_superblock retnp;
char *buf = malloc(1024);
int i1 = 0;
//char *tmpbuf = malloc(4);
/*if(i != 0)
    ata_read_master(buf,((i * 4)/256),0x00);
else{
    kprintf("[WRN]: Looking for superblock at offset 1024\n");
    ata_read_master(buf,4,0x00);
}*/
ata_read_master(buf,2,0x00);
const char *cmp = strsep(buf,0,4);


retnp.ninode = comb(strsep(buf,0,4),4);

    retnp.nblock = comb(strsep(buf,4,4),4);
    retnp.nsblock = comb(strsep(buf,8,4),4);
    retnp.nunallocb = comb(strsep(buf,12,4),4);
    retnp.nunalloci = comb(strsep(buf,16,4),4);
    retnp.supernum = comb(strsep(buf,20,4),4);
    retnp.leftshiftbs = comb(strsep(buf,24,4),4);
    retnp.leftshiftfs = comb(strsep(buf,28,4),4);
    retnp.numofblockpg= comb(strsep(buf,32,4),4);
 //   retnp.numofffpbg= comb(strsep(buf,36,4));
    retnp.numoffpbg = comb(strsep(buf,36,4),4);
    retnp.numofinpbg = comb(strsep(buf,40,4),4);
    retnp.lastmount = comb(strsep(buf,44,4),4);
    retnp.lastwrite = comb(strsep(buf,48,4),4);
    retnp.fsckpass = comb(strsep(buf,52,2),2);
    retnp.fsckallow = comb(strsep(buf,54,2),2);
    retnp.sig = comb(strsep(buf,56,2),2);
    retnp.state = comb(strsep(buf,58,2),2);
    retnp.erroropp = comb(strsep(buf,60,2),2);
    retnp.minorpor = comb(strsep(buf,52,2),2);
    retnp.ptimefsck = comb(strsep(buf,64,4),4);
    retnp.inter = comb(strsep(buf,68,4),4);
    retnp.osid = comb(strsep(buf,72,4),4);
retnp.mpv = comb(strsep(buf,76,4),4);
    retnp.uid = comb(strsep(buf,80,2),2);
retnp.gid = comb(strsep(buf,82,2),2);
ret = &retnp;
return ret;
i1 = 0;


}

如果有任何方法可以避免转换并成功实施 ext2,我会很高兴听到。我更喜欢它在 c 中,但汇编也可以。

【问题讨论】:

  • 请将相关代码内嵌为文本而不是链接
  • @EdChum 好的,我会在一秒钟内
  • "我需要转换成十进制,因为解析超级块需要所有值都是十进制。"我认为您处于非常错误的抽象级别。我认为您不需要在这里解析或转换任何内容。只需按原样获取值,也许将它们组合成超过 1 个字节的值。但我真的不认为需要转换为或 drom 文本。
  • @ZachS 如果您认为,例如int x = 4711; 以某种方式在x 中添加了一个“十进制”值,我相信您已经深入编写操作系统和文件系统驱动程序。这不是真的,你的问题毫无意义(正如@glglgl 所指出的那样)。将四个压缩字节转换为整数与“将十六进制转换为十进制”无关。
  • @ZachS 那是原始二进制数据,它不是十六进制格式,这只是您碰巧查看数据的一个属性。 char str[] = { 0, 0, 1 }; 是完全相同的数据,但以十进制表示。

标签: c++ c filesystems hex osdev


【解决方案1】:

如果你有这个:

const uint8_t bytes[] = { 0, 0, 1 };

并且您想考虑以小端顺序排列(24 位)无符号整数的字节,您可以使用以下方法转换为实际整数:

const uint32_t value = ((uint32_t) bytes[2] << 16) | (bytes[1] << 8) | bytes[0];

这将设置 value 等于 65536。

【讨论】:

  • 谢谢,我回家试试看
【解决方案2】:

您可以使用std::istringstreamsscanf 而不是自己编写。

char const * hex_text[] = "0x100";
const std::string hex_str(hex_text);
std::istringstream text_stream(hex_str);
unsigned int value;
text_stream >> std::ios::hex >> value;
std::cout << "Decimal value of 0x100: " << value << "\n";

或者使用sscanf:

sscanf(hex_text, "0x%X", &value);
std::cout << "Decimal value of 0x100: " << value << "\n";

在编写自己的函数之前,最好在 C++ 参考中搜索现有函数或搜索 Internet。

自己动手:

unsigned int hex2dec(const std::string& hex_text)
{
  unsigned int value = 0U;
  const unsigned int length = hex_text.length();
  for (unsigned int i = 0; i < length; ++i)
  {
    const char c = hex_text[i];
    if ((c >= '0') && (c <= '9'))
    {
       value = value * 16 + (c - '0');
    }
    else
    {
      c = toupper(c);
      if ((c >= 'A') && (c <= 'Z'))
      {
         value = value * 16 + (c - 'A') + 10;
      }
    }
  }
  return value;
}

要转换为使用 C 样式的字符串,请更改参数类型并使用 strlen 作为长度。

【讨论】:

  • 我无权访问 c 库
  • 大多数现代编译器,包括那些用于嵌入式系统的编译器,都有这些类型的库。
  • 如果十六进制文本写成字符串,它看起来像 "\0\0\1" ,它并不是一个字符串。但是我正在考虑将它放入一个字符串中,但是当我在家时我会这样做
  • 您是否尝试将一个或多个字节转换为更大的十六进制值?如果是这样,字节顺序是什么,Big Endian 还是 Little Endian?
  • 我相信它是小端,但当我回到家时我会确定
猜你喜欢
  • 2018-01-31
  • 1970-01-01
  • 2022-07-22
  • 2018-01-22
  • 2018-01-03
  • 1970-01-01
  • 2017-08-12
  • 2012-02-03
  • 1970-01-01
相关资源
最近更新 更多