关于Unicode和ANSI字符集处理

时间:2022-11-16 12:16:25

最近重温了一下孙鑫的《MFC深入详解》,遇到一个关于字符串处理的问题,孙鑫的源代码如下:

void CAddDlg::OnBnClickedButtonAdd()

{

int num1,num2,num3;

TCHAR c1[10],c2[10],c3[10];

GetDlgItem(IDC_EDIT_ADD)->GetWindowText(c1,10);
GetDlgItem(IDC_EDIT_BEADD)->GetWindowText(c2,10);
num1 = atoi(c1);
num2 = atoi(c2);
num3 = num1+num2;
itoa(num3,c3,10);
GetDlgItem(IDC_EDIT_SUM)->SetWindowText(c3);

}

这里孙鑫是在VC6.0中进行开发,我用的是VS2008,使用孙鑫的代码,会有以下报错:

 “atoi”: 不能将参数 1 从“TCHAR [10]”转换为“const char *”

这里先介绍以下TCHAR 是一个什么类型的变量,通过转到定义,发现其在Windows中定义如下:

      #ifdef UNICODE
      typedef wchar_t TCHAR;
      #else
      typedef char TCHAR;
      #endif

这里char类型大家可以肯定在C++的一些基础书籍上接触过,表示字符变量,其中存储的是字符。书中的字符都是采用的ASCII编码。

wchar_t 其实就是Unicode中的字符类型。所以TCAHR其本身的类型是根据是否定义UNICODE宏来确定的,使用这种方式来定义字符变量是为了代码的可移植性,那么如何判断是否定义了UNICODE宏,我们进入工程的属性菜单,会弹出如下对话框:

关于Unicode和ANSI字符集处理

在其中可以选择编码方式是Unicode还是ANSI编码,这里我猜想如果选择Unicode编码则会定义UNICODE宏吧。

在有了以上铺垫后理解这个错误就很容易了,VS2008中默认的都是采用Unicode编码,因此这里TCHAR的类型就是wchar_t 类型的,而atoi()函数的定义是这样的:int atoi(const char *nptr);明显参数类型是不匹配的,所以会有如上的报错。

所以解决方法其实有两种,方法一:将工程的编码方式由Unicode编码改为多字节编码,也即为ANSI编码。这时候TCHAR的类型是char类型的,既不会报错。

关于Unicode和ANSI字符集处理

方法二:

这种方法不用atoi()函数,其实对于字符串的处理函数,根据字符编码类型有两种:

ANSI        UNICODE           通用
   (char.h)          (wchar.h)        (tchar.h)

char         wchar_t              TCHAR

char *       wchar_t *          PTCHAR (PTSTR,LPWSTR,PWSTR,WCHAR)

printf       wprintf        _tprintf
      scanf       wscanf        _tscanf

atoi         _wtoi           _ttoi
      atol         _wtol           _ttol
      itoa         _itow           _itot
      ltoa         _ltow           _ltot

atof         _wtof           _tstof

strlen       wcslen          _tcslen
     strcat       wcscat          _tcscat
     strcpy      wcscpy           _tcscpy
     strcmp     wcscmp            _tcscmp

这里使用通用的函数_ttoi()即可解决问题。第一次写博客,算是个开始吧,格式也没有排版好,关于技术上的东西也不是很准确,不过算是一个开始吧。