c語言中如何將16進制字符串轉化成10進制整數?
#include <stdio.h>
#include <stdlib.h>
#include <string.h >
int zh(char s[])
{
int i,m,temp=0,n;
m=strlen(s);//十六進制是按字符串傳進來的,所以要獲得他的長度
for(i=0;i<m;i++)
{
if(s[i]>='A'&&s[i]<='F')//十六進制還要判斷他是不是在A-F或者a-f之間a=10。。
n=s[i]-'A'+10;
else if(s[i]>='a'&&s[i]<='f')
n=s[i]-'a'+10;
else n=s[i]-'0';
temp=temp*16+n;
}
return temp;
}
int main()
{
char s[10];
gets(s);
int n=zh(s);
printf("%d\n",n);
return 0;
}
第二種寫法(用switch ……case語句)
#include<iostream>
#include<string>
#include<functional>
#include<cctype>
#include<vector>
#include<algorithm>
using namespace std;
string add(const string &a,const string &b);
string multiply(const string &a,char b);
string multi(const string &a,const string &b);
int main(){
string b;
cin>>b;
//b="12345k,mbnw{6789abxcdEf";
b.erase(remove_if(b.begin(),b.end(),not1(ptr_fun(isxdigit))),b.end());
cout<<b.c_str();
//12345b6789abcdEf
vector<string> s;
string sum="1";
for(int j=0;j!=b.size();++j){
for(int i=1;i!=b.size()-j;++i)
sum = multi(sum,"16");
s.push_back(sum);
sum="1";
}
sum="0"; string first;
for(int j=0;j!=b.size();++j)
{
switch(b[j])
{
case 'a':
case 'A':
first="10";
break;
case 'b':
case 'B':
first="11";
break;
case 'c':
case 'C':
first="12";
break;
case 'd':
case 'D':
first="13";
break;
case 'e':
case 'E':
first="14";
break;
case 'f':
case 'F':
first="15";
break;
default:
first=string(1,b[j]);
}
sum=add(sum,multi(first,s[j]));
}
cout<<endl;
cout<<sum;
system("pause");
}
string add(const string &a,const string &b)
{
string sh,lo,r; int g=0;
if(a.size()>b.size())
{
sh=string(a.size()-b.size(),'0');
sh+=b; lo=a;
}
else
{
sh=string(b.size()-a.size(),'0');
sh+=a; lo=b;
}
r.resize(sh.size());
for(int i=sh.size()-1;i>=0;--i)
{
r[i]=sh[i]+lo[i]-48+g;
if(r[i]>'9')
{
r[i]-=10;
g=1;
}
else
{
g=0;
}
}
if(g==1)
r="1"+r;
return r;
}
string multiply(const string &a,char b)
{
string r;
r.resize(a.size()); int g=0;
if(b=='0')
return "0";
if(b=='1') //加快計算
return a;
for(int i=a.size()-1;i>=0;--i)
{
r[i]=(a[i]-48)*(b-48)%10+48+g;
if(r[i]>'9')
{
r[i]-=10;
g=((a[i]-48)*(b-48))/10+1;
continue;
}
g=((a[i]-48)*(b-48))/10;
}
if(g!=0)
r.insert(0,string(1,g+48));
return r;
}
string multi(const string &a,const string &b)
{
string r("0");
string *c=new string[b.size()];
for(int i=0;i<b.size();++i)
{
c[i]=multiply(a,b[b.size()-1-i])+string(i,'0');
r=add(r,c[i]);
}
delete[] c;
return r;
}
第三種(按照十六進制轉換十進制的微機原理思想)
1. 判斷是爲0-9或者是A-F或者a-f
2. 根據判斷利用權值法轉換n1*16^0+n2*16^1……
#include "stdio.h"
#include "string.h"
#define MAXLEN 80
int main(void)
{
char ch;
char str[MAXLEN], num[MAXLEN];
int i, k;
int repeat, ri;
long number;
scanf("%d", &repeat);
getchar();
for(ri = 1; ri <= repeat; ri++)
{i = 0;
while((ch = getchar()) != '\n')
{
str[i]=ch;
i++;
}
str[i] = 0;
k=0;
ch=i;
for(i=0;i<ch;i++)
{
if((0<=str[i]<=9)&&(A<=str[i]<=F))
{num[k]=str[i];
k++;
}
}
for(i=0;i<k;i++)
{if(num[i]==A) str[i]=10;
if(num[i]==B) str[i]=11;
if(num[i]==C) str[i]=12;
if(num[i]==D) str[i]=13;
if(num[i]==E) str[i]=14;
if(num[i]==F) str[i]=15;
}
number=0;
for(i=0;i<k;i++)
{ch=num[i]*16^(k-1);
number=number+ch;
}
printf("Dec = %ld\n",number);
}
}
第四種方法(16to2位運算)
//將16進制的一個字符轉換爲十進制的數
unsigned char CConvNumsDlg::BtoH(char ch)
{
//0-9
if (ch >= '0' && ch <= '9')
return (ch - '0');
//9-15
if (ch >= 'A' && ch <= 'F')
return (ch - 'A' + 0xA);
//9-15
if (ch >= 'a' && ch <= 'f')
return (ch - 'a' + 0xA);
return(255);
}
//轉換十進制數
void CConvNumsDlg::OnDecimalConv()
{
UpdateData(TRUE);
//先轉換爲二進制
m_strBinary = DecimalToBinary(m_strDecimal);
//再轉換爲十六進制
m_strHex = BinaryToHex(m_strBinary);
UpdateData(FALSE);
}
//轉換二進制數
void CConvNumsDlg::OnBinaryConv()
{
UpdateData(TRUE);
//轉換爲十進制
m_strDecimal = BinaryToDecimal(m_strBinary);
//轉換爲十六進制
m_strHex = BinaryToHex(m_strBinary);
UpdateData(FALSE);
}
//轉換十六進制數
void CConvNumsDlg::OnHexConv()
{
UpdateData(TRUE);
//先轉換爲二進制
m_strBinary = HexToBinary(m_strHex);
//再轉換爲十進制
m_strDecimal = BinaryToDecimal(m_strBinary);
UpdateData(FALSE);
}
//轉換十六進制爲二進制
CString CConvNumsDlg::HexToBinary(CString strHex)
{
int nLenth = strHex.GetLength();
char* Hex = new char[nLenth];
Hex = strHex.GetBuffer(0);
CString strBinary = "";
for(int i=0;i<nLenth;i++)
{
//轉換一位十六進制數爲十進制
char h = Hex[nLenth-1-i];
int j = BtoH(h);
CString str;
str.Format("%d",j);
//轉換十進制爲4爲二進制
str = DecimalToBinary(str);
strBinary += str;
}
return strBinary;
}
//轉換二進制爲十六進制
CString CConvNumsDlg::BinaryToHex(CString strBinary)
{
int nLength = strBinary.GetLength();
CString str = strBinary;
//位數不是四的倍數時補齊
switch(nLength%4)
{
case 0:
break;
case 1:
strBinary.Format("%d%d%d%s",0,0,0,str);
break;
case 2:
strBinary.Format("%d%d%s",0,0,str);
break;
case 3:
strBinary.Format("%d%s",0,str);
break;
default:
return "";
break;
}
CString strHex,str1;
str1 = "";
nLength = strBinary.GetLength();
for(int i=1;i<=(nLength/4);i++)
{
//每四位二進制數轉換爲一十六進制數
str = strBinary.Left(4);
CString strDecimal = BinaryToDecimal(str);
int nDecimal = atoi(strDecimal.GetBuffer(0));
if(nDecimal<10)
str1.Format("%d",nDecimal);
else
{
char c = 'A' + (nDecimal-10);
str1.Format("%c",c);
}
strHex += str1;
strBinary = strBinary.Right(strBinary.GetLength()-str.GetLength());
}
return strHex;
}
//轉換十進制爲二進制
CString CConvNumsDlg::DecimalToBinary(CString strDecimal)
{
int nDecimal = atoi(strDecimal.GetBuffer(0));
int nYushu; //餘數
int nShang; //商
CString strBinary = "";
char buff[2];
CString str = "";
BOOL bContinue = TRUE;
while(bContinue)
{
nYushu = nDecimal%2;
nShang = nDecimal/2;
sprintf(buff,"%d",nYushu);
str = strBinary;
strBinary.Format("%s%s",buff,str);
nDecimal = nShang;
if(nShang==0)
bContinue = FALSE;
}
return strBinary;
}
//轉換二進制爲十進制
CString CConvNumsDlg::BinaryToDecimal(CString strBinary)
{
int nLenth = strBinary.GetLength();
char* Binary = new char[nLenth];
Binary = strBinary.GetBuffer(0);
int nDecimal = 0;
for(int i=0;i<nLenth;i++)
{
char h = Binary[nLenth-1-i];
char str[1];
str[0] = h;
int j = atoi(str);
for(int k=0;k<i;k++)
{
j=j*2;
}
nDecimal += j;
}
CString strDecimal;
strDecimal.Format("%d",nDecimal);
return strDecimal;
}
第五種(調用內置函數)
主要有兩個方法,其實都是對現有函數的使用:
方法1: sscanf()
函數名: sscanf
功 能: 從字符串格式化輸入
用 法: int sscanf(char *string, char *format[,argument,...]);
以上的 format 爲 %x 就是將字符串格式化爲 16 進制數
例子:
#include <stdio.h>
void main()
{
char* p = "0x1a";
int nValude = 0;
sscanf(p, "%x", &nValude);
printf("%d\r\n", nValude);
}
輸出:
26
方法2: strtol()
函數名: strtol
功 能: 將字符串轉換爲長整數
用 法: long strtol(char *str, char **endptr, int base);
上面的base就是我們要轉換爲幾進制數
例子:
#include <stdio.h>
#include <stdlib.h>
void main()
{
char* p = "0x1b";
char* str;
long i = strtol(p, &str, 16);
printf("%d\r\n", i);
}
輸出:
27
其實還有一種方法,就是用一個初始化爲0~9~a~f的字符串數組,也就是一個十六進制對應表,用這個對應表即可算出一個十六進制字符串的數值,但這種發發太麻煩了,不推薦使用