在c中将十六进制字符串转换为十进制
Convert string of hexadecimal to decimal in c
我正在用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中,但汇编也可以。
您可以使用 std::istringstream
或 sscanf
而不是自己编写。
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
作为长度。
如果你有这个:
const uint8_t bytes[] = { 0, 0, 1 };
并且您想考虑小端顺序的(24 位)无符号整数的字节,您可以使用以下方法转换为实际整数:
const uint32_t value = ((uint32_t) bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
这将使 value
等于 65536。
我正在用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中,但汇编也可以。
您可以使用 std::istringstream
或 sscanf
而不是自己编写。
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
作为长度。
如果你有这个:
const uint8_t bytes[] = { 0, 0, 1 };
并且您想考虑小端顺序的(24 位)无符号整数的字节,您可以使用以下方法转换为实际整数:
const uint32_t value = ((uint32_t) bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
这将使 value
等于 65536。