最近重温了一下孙鑫的《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中定义如下:
这里char类型大家可以肯定在C++的一些基础书籍上接触过,表示字符变量,其中存储的是字符。书中的字符都是采用的ASCII编码。
而wchar_t 其实就是Unicode中的字符类型。所以TCAHR其本身的类型是根据是否定义UNICODE宏来确定的,使用这种方式来定义字符变量是为了代码的可移植性,那么如何判断是否定义了UNICODE宏,我们进入工程的属性菜单,会弹出如下对话框:
在其中可以选择编码方式是Unicode还是ANSI编码,这里我猜想如果选择Unicode编码则会定义UNICODE宏吧。
在有了以上铺垫后理解这个错误就很容易了,VS2008中默认的都是采用Unicode编码,因此这里TCHAR的类型就是wchar_t 类型的,而atoi()函数的定义是这样的:int atoi(const char *nptr);明显参数类型是不匹配的,所以会有如上的报错。
所以解决方法其实有两种,方法一:将工程的编码方式由Unicode编码改为多字节编码,也即为ANSI编码。这时候TCHAR的类型是char类型的,既不会报错。
方法二:
这种方法不用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()即可解决问题。第一次写博客,算是个开始吧,格式也没有排版好,关于技术上的东西也不是很准确,不过算是一个开始吧。