[转贴]VC中 十六进制字符串转换为十进制数字

    技术2022-05-20  56

    在程序中,我们有时需要将一个十六进制字符串转换为十进制数字。比如: char *ptr="0x11"; int n=0; //我们想让n等于0x11,即17 通常我们在C中,想将一个字符串转换为一整形数字,通常会使用下面的方法: view plaincopy to clipboardprint? char *ptr="123";       int n=0;   n=atoi(ptr);   printf("%d/n",n);     //输出:123  char *ptr="123"; int n=0; n=atoi(ptr); printf("%d/n",n); //输出:123 但是atoi库函数只能将十进制字符串转化为int整形,比如下面的例子: view plaincopy to clipboardprint? #include <stdlib.h>    #include <stdio.h>//atoi头文件      int main(void)    {       int n;       char *str = "12345.67";         n = atoi(str); //int atoi(const char *nptr);       printf("string = %s integer = %d/n", str, n);       return 0;    }   /*输出:    string = 12345.67 integer = 12345  */  #include <stdlib.h> #include <stdio.h>//atoi头文件 int main(void) {    int n;    char *str = "12345.67";    n = atoi(str); //int atoi(const char *nptr);    printf("string = %s integer = %d/n", str, n);    return 0; } /*输出:   string = 12345.67 integer = 12345 */ 所以要用atoi函数将"0x11"转化为十进制整形17是不行的。如果用的话,会输出下面的结果: view plaincopy to clipboardprint? int n;    char *str = "0x11";      n = atoi(str); //返回值n等于0 (显然不是我们想要的结果)     int n;    char *str = "0x11";    n = atoi(str); //返回值n等于0 (显然不是我们想要的结果) 那怎么办呢?这时有人会想,那好办,我们自己写个函数转化下就行了,比如用下面的方法: 注意:我们用VC 6.0建了一个Win32控制台程序,为了方便,程序中使用了CString类型变量,需要做一点修改。 (1)包含afx.h头文件 (2)在Project->Settings->General->Mircosoft Foundation Classes中,选择Use MFC in a Shared DLL 然后我们就可以在Win32控制台下使用CString变量了,否则会出现编译错误。 view plaincopy to clipboardprint? #include <iostream>   #include <afx.h>     int ChangeNum(CString str,int length)      {          char  revstr[16]={0};  //根据十六进制字符串的长度,这里注意数组不要越界       int   num[16]={0};          int   count=1;          int   result=0;          strcpy(revstr,str);          for   (int i=length-1;i>=0;i--)          {              if ((revstr[i]>='0') && (revstr[i]<='9'))                  num[i]=revstr[i]-48;//字符0的ASCII值为48           else if ((revstr[i]>='a') && (revstr[i]<='f'))                  num[i]=revstr[i]-'a'+10;              else if ((revstr[i]>='A') && (revstr[i]<='F'))                  num[i]=revstr[i]-'A'+10;              else                  num[i]=0;            result=result+num[i]*count;              count=count*16;//十六进制(如果是八进制就在这里乘以8)           }          return result;      }     int main()   {       CString   str="0x11";        int n=0;       n=ChangeNum(str,str.GetLength());       printf("%d/n",n);           return 0;      }   /*输出:    17  */  #include <iostream> #include <afx.h> int ChangeNum(CString str,int length)   {   char  revstr[16]={0};  //根据十六进制字符串的长度,这里注意数组不要越界 int   num[16]={0};   int   count=1;   int   result=0;   strcpy(revstr,str);   for   (int i=length-1;i>=0;i--)   {     if ((revstr[i]>='0') && (revstr[i]<='9'))      num[i]=revstr[i]-48;//字符0的ASCII值为48   else if ((revstr[i]>='a') && (revstr[i]<='f'))      num[i]=revstr[i]-'a'+10;     else if ((revstr[i]>='A') && (revstr[i]<='F'))      num[i]=revstr[i]-'A'+10;     else      num[i]=0;   result=result+num[i]*count;     count=count*16;//十六进制(如果是八进制就在这里乘以8)    }   return result;   } int main() { CString   str="0x11"; int n=0; n=ChangeNum(str,str.GetLength()); printf("%d/n",n);         return 0; } /*输出:   17 */ 是的,上面方法可以得到我们想要的值。还有更简单的方法吗?当然有! 方法1: view plaincopy to clipboardprint? #include <stdio.h>     int main()   {       char   szValue[]  =   "0x11";          int    nValude    =   0;              sscanf(szValue,"%x",&nValude);          printf("%d/n",nValude);       return 0;      }   /*输出:    17  */  #include <stdio.h> int main() {     char   szValue[]  =   "0x11";       int    nValude    =   0;           sscanf(szValue,"%x",&nValude);       printf("%d/n",nValude);     return 0; } /*输出:   17 */ 主要用到sscanf这个库函数: 函数名: sscanf 功  能: 执行从字符串中的格式化输入 用  法: int sscanf(char *string, char *format[,argument,...]); //%x就是我们要格式化的类型,即输出十六进制 方法2: view plaincopy to clipboardprint? #include <stdio.h>   #include <stdlib.h>//strtol头文件     int main()   {       char *p="0x11";          char *str;          int i = (int)strtol(p, &str, 16);//十六进制       printf("%d/n",i);       return 0;      }   /*输出:    17  */  #include <stdio.h> #include <stdlib.h>//strtol头文件 int main() {     char *p="0x11";       char *str;       int i = (int)strtol(p, &str, 16);//十六进制     printf("%d/n",i);     return 0; } /*输出:   17 */ 主要用到strtol这个库函数,它的使用方法是: 函数名: strtol 功  能: 将串转换为长整数 用  法: long strtol(char *str, char **endptr, int base);//base指明我们要转换为几进制数 程序例: view plaincopy to clipboardprint? #include <stdlib.h>    #include <stdio.h>      int main(void)    {       char *string = "0x11", *endptr;       long lnumber;         /* strtol converts string to long integer */       lnumber = strtol(string, &endptr, 16);       printf("string = %s  long = %ld/n", string, lnumber);         return 0;    }    /*输出:    string = 0x11 long = 17  */  #include <stdlib.h> #include <stdio.h> int main(void) {    char *string = "0x11", *endptr;    long lnumber;    /* strtol converts string to long integer */    lnumber = strtol(string, &endptr, 16);    printf("string = %s  long = %ld/n", string, lnumber);    return 0; } /*输出:   string = 0x11 long = 17 */ 在VC 6.0的MFC程序中,我们有时要转换句柄就可以用strtol这个函数,比如: view plaincopy to clipboardprint? HANDLE handle = (HANDLE)strtol(str,NULL, 16);  HANDLE handle = (HANDLE)strtol(str,NULL, 16); PS:句柄是什么? 句柄就是用来区分各种内存对象的唯一标识符号,是个32位整数。 有些是整个系统唯一(如窗口句柄),有些是当前进程或线程中唯一(如线程句柄,全局的有另一个标识符)。 详细的可分为许多种,都是以H开头的。在VB中使用时全部都用Long。 常见的有窗口句柄(HWND),设备描述表句柄(HDC),内存句柄(HMEM),文件句柄,进程句柄,线程句柄,笔的类型句柄(HPEN),字体句柄(HFONT),区域句柄(HRGN)等等。 在申请句柄时是要占用资源的,分三类SYSTEM、USER、GDI。而WINDOWS的资源是固定的,并不随内存的扩大而扩大,所以使用完以后一定要释放。 方法3: 在网上,还看到一位朋友提出一种方法,就是读写INI文件(我认为这种方法效率太低,毕竟要读写文件的),也将其摘录如下: view plaincopy to clipboardprint? //存储HANDLE   struct Tag_STRUCT       {           HWND hWnd;       } ;       struct Tag_STRUCT Struct;         Struct.hWnd = m_hWnd;       //把包含句柄的结构体写入ini文件       WritePrivateProfileStruct("Section","Key",&Struct,sizeof(Struct),"C://1.ini");     //读取HANDLE       struct Tag_STRUCT       {           HWND hWnd;       } ;       struct Tag_STRUCT Struct;       //从包含句柄的结构体的ini文件读取HANDLE       GetPrivateProfileStruct("Section","Key",&Struct,sizeof(Struct),"C://1.ini");  //存储HANDLE struct Tag_STRUCT     {         HWND hWnd;     } ;     struct Tag_STRUCT Struct;     Struct.hWnd = m_hWnd;     //把包含句柄的结构体写入ini文件     WritePrivateProfileStruct("Section","Key",&Struct,sizeof(Struct),"C://1.ini"); //读取HANDLE     struct Tag_STRUCT     {         HWND hWnd;     } ;     struct Tag_STRUCT Struct;     //从包含句柄的结构体的ini文件读取HANDLE     GetPrivateProfileStruct("Section","Key",&Struct,sizeof(Struct),"C://1.ini");

    【转自:http://fiona1011.iteye.com/blog/634541】


    最新回复(0)