2015-12-02 81 views
-2

我正在用C語言和程序集編寫操作系統,並且在實現EXT2文件系統時遇到了問題。我需要在C中將十六進制的四個字節轉換爲十進制。例如,將00 00 0110000)轉換爲65536。我需要轉換爲十進制,因爲解析超級塊需要所有值都是十進制。最特別的ext2文件我的工作是在這裏:
將十六進制字符串轉換爲c中的十進制數

#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,但大會也沒關係。

+1

請在線發佈相關的代碼作爲文本而不是鏈接 – EdChum

+0

@EdChum沒關係,我會在幾秒鐘之 –

+3

「我需要轉換爲十進制,因爲解析超級塊需要所有值都是十進制。」我認爲你的抽象程度非常高。我不認爲你需要在這裏解析或轉換任何東西。只要按照原樣取值,也許將它們組合起來形成長於1個字節的值。但我真的不認爲需要轉換爲或文本。 – glglgl

回答

1

如果你有這樣的:

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

,你要考慮的是在little-endian順序一(24位)無符號整數的字節,則可以使用轉換成實際的整數:

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

這將設置value等於65536

+0

謝謝,我會嘗試,當我回家 –

0

您可以使用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++參考現有的功能或在互聯網上搜索,寫你自己的了。

推出自己的:

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的長度。

+0

我無法訪問c庫 –

+1

大多數現代編譯器(包括用於嵌入式系統的編譯器)都有這些庫。 –

+0

@ZachS看我的編輯。 –

相關問題