我把vc6.0上运行没有问题的代码挪到vs2010上,出现了一系列问题。
其根本原因是两种编译器默认编码不一样,vc6.0中默认的编码是(多字节)Ascii编码,VS2010中默认的编码是Unicode编码。
可以简单粗暴地改回去
打开菜单栏–>项目–>XXX属性–>配置属性–>常规–>字符集–>设置回Ascii编码
编译没有问题。
看了一下两种编码的区别:
ANSI 在不同的操作系统下代表着不同的编码。在我们正常用的简体中文windows操作系统中,ANSI代表着GBK编码,而在日文Windows操作系统中,ANSI 编码代表 Shift_JIS 编码。不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。
UNICODE是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode
是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
作者:米奇小林
CString与char*互转及ANSI 和 UNICODE 编码
https://www.jianshu.com/p/9804c28e21e8 來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
那么,什么是字符集? 规定二进制数据和某种语言内的文字之间的对应关系,这就叫该种语言的字符集 最基本的是ASCII,规定数值48对应字符’0’,诸如此类,但由于这种对应关系的历史局限性(发明它的人当时没兴趣考虑非英文语言),同样的二进制数据,在不同的字符集内就对应不同的文字 而规定一套对应关系,使得二进制数据能够对应很多语言的文字,这就叫Unicode
使用Unicode编码显然更好。
所以我最后还是改回去了。
第一个问题是
error C2664: ‘strtol’ : cannot convert parameter 1 from ‘CString’ to ‘const char *’
不能将参数 1 从“CString”转换为“const char *”;
text=strtol(m_recieve,NULL,16);
//其中text为long型,m_recieve为CString型。
strtol函数的功能是转换字符串为长整形数字。
上面那句代码的意思是:把m_recieve这个字符串转换成16进制数并赋值给text。
但是在Unicode编码下出错了,因为在这个long strtol(const char *nptr,char **endptr,int base);
函数中变量的字符串类型是const char,而Unicode编码下的字符串类型是const wchar_t。
所以要改成text=wcstol(m_recieve,NULL,16);
//关于这两个函数:
long wcstol(const wchar_t *nptr,wchar_t **endptr,int base);
long strtol(const char *nptr,char **endptr,int base);
参数:
1、nptr,需要转换的以’\0’作为终止符的字符串指针
2、endptr,如果有,则转换到该指针位置就停止
3、base,转换中如果遇到大于或等于base的字符就停止,一般设置为10
注意:
1、如果超出long上线,返回LONG_MAX或LONG_MIN
2、如果无法解析,返回0
第二个问题是:
error C2593: ‘operator =’ is ambiguous 不明确
定义了一个CString 对象m_strInputLine 在消息处理函数中:
void CTextView::OnChar (UINT nChar, UINT nRepCnt, UINT nFlags)
{
m_strInputLine += nChar;
}
问题在于
CString,在vs2010中,为unicode,wchar_t基类型。
而CString,在vc6.0中为ansi,char基类型。
所以上述代码中的m_strInputLine是wchar_t,而定义的时候nchar是无符号整型。
所以我们必须强制类型转换,将UINT nChar转换成wchar_t。
pDoc->StringData += nChar;
编译时出现“operator +=”不明确改正方法:
pDoc->StringData+=(char)nChar,因为系统里面存在一个wchar_t的类型,所以如果支持了这个类型的话,从unsigned nt转换到wchar_t和char的等级都是标准转换,所以编译器无法判断到底应该转换到哪一个,故而导致了这个问题。
m_space=m_space+" ";
把char型改为wchar_t类型:
m_space=m_space+(wchar_t)" "
第三个问题是:
【error】LINK1123: failure during conversion to COFF: file invalid or corrupt
意思是由于COFF标识转换失败。而在连接中完成此项工作的是cvtres.exe。这个错误的原因是存在多个版本的cvtres.exe。
所以找到这个文件删掉就好了
第四个问题是:
error C1189: #error : Please use the /MD switch for _AFXDLL builds
解决方法:
修改设置:工程(Project)-> 属性(Properties)-> 配置属性(Configuration Properties)-> c/c+±> 代码生成(Code Generation)->运行库(Use run-time library)->多线程调试DLL(/MD)
//百度了一下那几个选项什么意思:
多线程DLL(/MD):在dll中使用多线程,创建动态链接库的release版本,需要选择。
多线程(/MT): 在exe里使用多线程,创建exe的release版本,需要选择。
多线程调试(/MTd):同/MT一样,不过是在Debug版本中使用。
多线程dll调试(/MDL):同/MD一样,不过是在Debug版本中使用。
第五个问题是在编译已经没有error,运行的时候弹出来的提示:
Run-Time Check Failure #2 - Stack around the variable “XX” was corrupte
中文翻译就是“在变量XX周围的堆栈已损坏”。
意思是在我们的程序中,在某个变量附近的内存被破坏了,如果出现此类问题,一般表示我们的程序存在内存越界。MSDN的解释是在堆栈外面读写某数据。
最后我是把“project->配置属性->c/c+±>代码生成->基本运行时检查 设置为默认值,就没有这样的错误了。
我觉得还是两种编码转换的原因使得数据变大了,但是我看不出来:
CString,在vs2010中,为unicode,wchar_t基类型。
而CString,在vc6.0中为ansi,char基类型。
所以看了一下wchar_t和char的区别:
对于ascii码的char事实上就是unicode码wchar的首个字节码。
窄字符char就是8bit表示的byte,长度固定。char字符只能表示ASII码表中的256个字符,包括前128个可见字符和后面的128个不可见字符。
而wchar_t则是因为char所能表示的字符数太少(256个)而应运而生的,它的长度可以8bit,16bit,32bit,长度是与不同平台上的c库相关的。其实这个长度是根据指定平台上想要用的encoding编码方式来设定的。
char可以用来指向各种数据的内存,不是因为它们都是char字符数据,而是因为char的大小是1个字节,方便指针控制(如果你要用void指向各种内存,概念上是更加正确了,你试试看怎么偏移指针)
wchar_t其实就是typedef的2字节short,也就是对应unicode的编码范围为2字节数据,用的就是这种数据类型的字节数而已
所以char和wchar_t指向同一段内存,有什么错?一点错误都没有,它们都只指向这一段二进制数据而已,区别就在于你使用这两种类型的指针来操作数据的时候,按照相应的类型来操作这段内存,仅此而已。
应该就是char变成wchar_t导致的error吧,有人知道怎么改吗?
最后一个问题就是我运行程序的时候显示出乱码“00ᅠFCᅠ80ᅠ92ᅠ80ᅠ82ᅠ80ᅠ81ᅠEEᅠFFワ”和“12歠02歠00歠01歠6E歠01歠70歠00歜”或者“12歠02歠00歠01歠6E歠01歠70歠00\”
我真是绝望了。。。
最后莫名其妙地从
改成
最后改成这样终于好了
我还是不太懂这种字符串的转换,有空再找书仔仔细细地看吧…
最后马克一下我觉得非常有用的tips,虽然他的主人写的不明不白的:
原地址:https://www.cnblogs.com/judes/p/6146795.html
unicode下数据之间的转换
首先mfc下字符串只有两种数据:char(一个字节)和wchar_t(两个字节),很多其他数据类型如TCHAR,WCHAR等都是这个两个基本类型的宏定义,BYTE是uchar1、对话框打印char*
char* info="";
::MessageBoxA(this->m_hWnd, info, “”, MB_OK);
2、CString转char*
int nLen; char * wsabuf = NULL; USES_CONVERSION; wsabuf =
W2A(send_txt_str);//send_txt_str为CString消息3、char*转CString
直接强制转换
4、_T(“AA”)转0xAA
BYTE byte1 = wcstol(_T(“AA”), NULL, 16);
5、_T(“你好”)转C4 E3 BA C3
用2的方法转char*->BYTE*,定义一个循环,在循环中定义一个临时CString变量Format取出单个BYTE元素
6、字符串转整数,“ff”、_T(“ff”)转256
用atoi那一系列函数(a代表ascii,to代表转化,i代表int)
同上还有itoa一系列函数
ttoi(),CString转整数
使用strtol系列函数:(str to long)
int a;
CString str;
str=_(“1234”);
a=wcstol(str,NULL,10);
a->1234
7、_T(“01FF”)转十进制:511
long a = wcstol(_T(“01FF”),NULL,16);//a=511
8、整数转字符串
_ltoa
9、把整数的十六进制转化成CString int a=20; CString temp_str;
temp_str.Format(_T("%02x"),20); 10、C4 E3 BA C3转_T(“你好”) 强制转换(CString)