首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

再谈unsigned char * 转换 AnsiString的怪有关问题

2012-02-04 
再谈unsigned char * 转换 AnsiString的怪问题这几天在处理一个加密解密的程序,一直是问题不断,实在脑人!

再谈unsigned char * 转换 AnsiString的怪问题
这几天在处理一个加密解密的程序,一直是问题不断,实在脑人!转正题:
加密程序用别人的,大致是用Encrypt(unsigned   char*   data,unsigned   char*   key)和Decrypt(unsigned   char*   data,unsigned   char*   key)两个方法处理加密解密。

void   __fastcall   TForm1::Button9Click(TObject   *Sender)
{
        unsigned   char   key[]= "12356789012345 ";
        AnsiString   str=Memo1-> Text;
        unsigned   char   *c1=(str).c_str();

        Encrypt(c1,key);//c1为传入数据,加密后再用c1传出。
        Memo2-> Text=(char*)c1;//Memo2内显示加密后的内容,看起来是乱码。

        Decrypt(c1,key);//c1为传入数据,加密后再用c1传出。注意此处直接用的c1,而不是Memo2的值。
        Memo3-> Text=(char*)c1;//Memo3内显示解密后的内容,与Memo1相同。
}

上面这段从结果看是正确的。但如果我要从Memo2中取出加密文再解密,发现解密后的内容只是源文的前一部分。我这才发现Memo2中的文本已经被截断,Memo1中的文本不一样,截断的位置也不一样,有的在100多位处截断,有的在4、5百处截断。
我跟踪查看截断处,发现经过加密后文本c1表面上已经截断,即最后一个字符是 '\0 '。但问题是c1已经被截断,但c1在后续工作中又是正确的,实在是晕。有哪位知道如何处理这个问题。

另外,unsigned   char*   到   char*转换到底会不会丢失数据。我在网上搜了一天,也没弄清楚,有的说会,有的说不会。我又晕了,见笑:)

[解决办法]
Memo中显示文本是正确的,加密之后有些字符是不可显示的,中间还可能有‘\0 '存在。
用Memo存放不可显示字符本身就是错误的
[解决办法]
不使用中间变量的原因是因为AnsiString是不确定的原因吗?那么以下有什么区别:

如果有方法为:
void f(char* data)
{
//针对data操作。
....
}

void main()
{
AnsiString str= "absd ";
char *c=str.c_str();
f(c);
}

void main()
{
AnsiString str= "absd ";
f(str.c_str());
}
有什么区别?最终都是传给另一个变量。
能不能再说明白一点,谢谢!


原因我估计是,当str重新赋值时,数据要重新分配内存,数据内存地址就变了
比如
AnsiString str= "absd ";
char *c=str.c_str();
AnsiString str= "absdasdasd ";
此时c的地址已经不是str.c_str()了,因为str重新分配过了,数据内存地址变了
[解决办法]
dephibegin() ( ) 信誉:100 Blog 2007-1-8 9:22:45 得分: 0


带红星星的人不厚道

=======================

是忒不厚道了,呵呵!

不是我不愿意回答,而是这种问题问过很多遍了,如果愿意学习的话完全可以用本版的搜索来解决问题,而且还能学到很多其它的东西。

既然有人说不厚道了,就说说吧。

-------------------------------------

先不说AnsiString和char*的问题,我觉得初学者首先要记住的就是对内存的管理,大多数情况下谁分配(new)的就由谁来释放(delete)。

AnsiString是一个类(class),它在内部实现了对内存的管理,使用者不必去理会。
char*是一个指针(pointer),指向一块内存,所以使用者必须负责它的分配和释放。
AnsiString.c_str() 返回的是类实体所管理的内存,第1这个地址可能会改变,第2对块内存的操作可能会破坏类的结构。

不使用中间变量只是一个习惯问题,并不是一定不能这么做,至少在语法是没有问题的。
就像把变量都命名为a,b,c...一样,虽然可以,但不建议这样做,也几乎没有程序这样做,除了一些不友好的小例子。

----------------------------------

楼主又问到16进制的问题,也有很多贴子。10进制和16进制有区别吗?对于计算机来说,只有0和1。如果说转换成16进制的字符串,当然是可逆的,所有的数据都可以转换成16进制的字符串, '\0 '、不可见字符、可见字符,对计算机来说没有区别。
[解决办法]
不要用AnsiString 类型,存放中Memo中也是这种类型。
直接放在unsigned char * 类型的内存中就行了。

如果要保存,可以放在文件中,可以用二进制形式。
如:
FILE *fp = fopen( "a.dat ", "wb ");
fwrite(data, 1, size, fp);
fclose(fp);
[解决办法]
如果要用16进制,且可显示的,可以象WinHex这些编辑器一样显示,类似:
00 0A BE F0
按照这样可以正确转回去,只是麻烦了,我认为没有必要用这种方式。

热点排行