打包解包模块总结:VS2010中默认的编码是Unicode编码

我把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是uchar

1、对话框打印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)

猜你喜欢

转载自blog.csdn.net/weixin_43580841/article/details/84038924