字符串数组如何清空? CString ip[200];memset(ip,0,sizeof(ip));这一句居然会导致程序运行时出错,这是怎么回事?原来想清空ip字符串数组。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 for (int i=0; i<200; i++){ ip[i].Empty();} 如果ip是字符串定义,如CString ip;那么ip.Empty()在VC编辑器里,是可以自动给出提示,可以选择的但如果ip是字符串数组定义,如CString ip[200];那么ip.Empty()在VC编辑器里,是无法自动给出提示可以选择的。也就是说,ip.Empty()这写法是不可以的。 给个简单的CString ip[200]={_T("")}; CString ip[200]是对象数组,用二楼的方法才正确。 为什么用memset(ip,0,sizeof(ip))不行呢?这不是更简单吗? CString数组在用时不用清空的,这个和字符数组不一样。 你这里是CString对象,不是字符串,类对象的处理方式不同与简单变量,其实CString变量在用之前不用清零的。 CString ip[200] 是200个CString类当实体对象组成的数组,而不是ip有200个字符空间……所以要使用上面的方法…… memset(ip,0,sizeof(ip))在这种情况下当然不行除非你是用char ip[200];CString是一个对象,需要初始化,构造函数的调用如果memset了,那这个对象就未经过初始化了 CString是个类,定义一个CString 对象,默认字符串就是空串 你上面说的CString ip[200]并不是字符串数组,这个是个CString的对象数组。CString是个封装了字符串的对象 CString ip[200];for(int i=0;i<200;i++){ ip[i].empty();}CString ip[200];为字符串数组CString ip;为字符串char szIp[200];为字符数组 那有CString ip[200];这样定义的!!CString *ip;ip=new CString[200];for (int i=0; i<200; i++){ ip[i].empty();} CString是类,不是简单变量,你知道一个CString对象有多大吗?CString的大小是固定的吗? CString是类,不是基本数据类型的数据 for (int i=0; i<200; i++){ ip[i].Empty();} CString 还不是一个Const char* 类型的变量吗?CString 的类型定义上不就是这么写的吗? CString 还不是一个Const char* 类型的变量吗?CString 的类型定义上不就是这么写的吗?============CString可不是const char *,CString是MFC提供的对字符串处理的类,和char *的差别可不是一般的大。 我的用法原意是这样的先定义字符串数组CString ip[200];然后使用中用IP字符串数组暂存一下一些字符串,再下一次循环使用前,先清空原已存储的IP字符串数组,重复使用IP数组空间。由于下一循环使用时,涉及的字符串数量有可能比上一次使用的数组有可能少,也有可能多,因此需要将201个IP字符串空间都清空一下。这样,二楼的CString ip[200]={_T("")};就不可行了。如果用for (int i=0; i<200; i++){ ip[i].Empty();}那效率太低了,如果循环的次数大的话,或有二层循环嵌循环,那对程序执行速度影响太大。因此征求更有效率的清空方法。 6楼的确实最简单。。但是CString对象构造的时候,应该是被清空了。。 33楼的楼主,CString 里面其实只是一个 char* 或 wchar* 的指针,你最初直接 把 CString 清零是很危险的动作,清的只是一个指针.sizeof(ip) 其实是 200 * 4(指针大小) = 800for (int i=0; i<200; i++){ ip[i].Empty();} 这个我查了一下内存,原来是把CString里面指向堆里的内容先 delete,操作上可能会慢上些.debug 了一下一个 CString 赋值的操作CString str = "123";CString str = "1234567890"; 这时由于长度变得更长了,CString的赋值操作函数会先delete原来的"123"处的内存,再重新new一个新的11个位置的内存来放新数据.之后再赋值 str = "abcd"; 由于长度小于之前的长度,str不会再次执行delete 与 new 的操作,只会在原来的地方写入 abcd\0 可以查到内存中的数据为 abcd\067890所以如果楼主想效率高的话,最好是一开始把CString 的长度设得大一些,避免以后再重复申请内存,然后下次直接赋值即可,不用再清零了. ip为ip这个数组的头指针 sizeof(ip)返回4位 ip是可以当作指针来用,是4字节,但sizeof知道ip定义时写成是数组,所以会知道是4*200 别学坏了他后面说的有问题这个不是CString有多大、是不是固定大小的问题,清空一个类、结构不需要知道有多大,sizeof就可以,大小是固定的,在编译的时候就确定了不用memset是因为类对象是初始化一般都是他的构造函数做的 大小是固定的,在编译的时候就确定了=======CString的对象大小应该是不固定的吧,CString a;的大小和a="kdjfkldjfkldj";的大小应该是不一样的吧。 CString 的大小是固定的.CString a;int iSize1 = sizeof(a);a = "aadfadffadfasd"int iSize2 = sizeof(a);永远是4看过CString 的代码,他里面就是一个指向堆的字符数组的指针,所以大小是4.大小不同的是在堆里面.不同的值,就不同大小了. 回35楼,“所以如果楼主想效率高的话,最好是一开始把CString 的长度设得大一些,避免以后再重复申请内存,然后下次直接赋值即可,不用再清零了."这句话不对,如果不清零,那字符串数组里的值会被带到下一个循环操作中,会形成误操作。 41楼,你的下一个手环操作,是 str = "abc" 还是 str += "abc" ,还是其他的代码?如果是 str="abc" 这样的话,的确是直接把最前面的改写,再加上一个0,然后后面的不动.我DEBGU过,查过内存的. 直接赋值后,如果短了,后面的内容不动,仍然在,但如果是字符操作的话,由于后面有0的,就不会影响.例如下面的代码. CString str = "123456789"; str = "abc"; MessageBox(str); //会输出 abc ,后面的内容没有影响 MessageBox((LPCTSTR)(str) + 4); //会输出56789,因为后面的内容还在 举个例子:一个程序有显示200个字符串的功能第一次循环得到四个字符串,如IP[0]="aaa1"IP[1]="aaa2"IP[2]="aaa3"IP[3]="aaa4"然后程序有个显示动作,在界面上显示这四个值,其它IP[N]都是空字符。第二次循环得到两个字符串IP[0]="b1"IP[1]="b2"然后程序有个显示动作,这时,在界面上会下面显示四个值,其它IP[N]都是空字符。IP[0]="b1"IP[1]="b2"IP[2]="aaa3" (这是因为没有清空的结果)IP[3]="aaa4" (这是因为没有清空的结果)所以,这个结果不是想要的,原来想要的显示结果如下IP[0]="b1"IP[1]="b2"所以高效地清空IP[]字符串数组就非常重要了。 CString str[200]; LARGE_INTEGER liFreq,liStart,liEnd; int i; for (i=0;i<200;i++) //先赋值,分配一下内存 { str[i] = "abc"; } QueryPerformanceFrequency(&liFreq); QueryPerformanceCounter(&liStart); for (i=0;i<200;i++) { str[i].Empty(); } QueryPerformanceCounter(&liEnd); double fCount = liEnd.QuadPart - liStart.QuadPart; TRACE("直接Empty用时____%.10f 秒\n",fCount/liFreq.QuadPart); QueryPerformanceCounter(&liStart); for (i=0;i<200;i++) { str[i] = ""; } QueryPerformanceCounter(&liEnd); fCount = liEnd.QuadPart - liStart.QuadPart; TRACE("写0清零用时______%.10f 秒\n",fCount/liFreq.QuadPart);用写0来清吧,测试过了一下,输出如下.直接Empty用时____0.0009060139 秒写0清零用时______0.0000265256 秒楼主,你说用for循环会慢,之前有朋友说过改为用while(--i)这类型的会快一些,但我度测过,while与for循环都是差不多的时间.我也没有深入去看汇编了. Empty()慢一些,但也不是说微软的清0函数差,Empty()是清掉堆里占的内存,减轻内存的占用. 47楼真强,顶50楼,有的时候我们真的只是在用VC的一些函数,而实际上并不是会用VC的函数。 元旦将至,祝大家元旦快乐! 怎样使Static Text控件的文字显示成多行 Delphi代码转VC 各位高手给看看这段代码为什么会使ToolBar无法正常显示? opengl摸板缓存问题,请指教 建立对话框时的三种style有什么不同? 如何打开一个有密码的数据库 请大家帮忙看一下下面的操作符重载的源程序,我在VC6下编译不能通过,这是我课本上的一个例子. 高手请进!!(52分)有关dll问题 各位大侠!我想请教一下:关于语音录制方面的一个问题!(给分多多!) 内存使用不断增加,然后就出错 求助,在VC++程序里怎么调用其它工具?
{
ip[i].Empty();
}
那么ip.Empty()在VC编辑器里,是可以自动给出提示,可以选择的
但如果ip是字符串数组定义,如CString ip[200];
那么ip.Empty()在VC编辑器里,是无法自动给出提示可以选择的。也就是说,ip.Empty()这写法是不可以的。
CString ip[200]={_T("")};
CString ip[200] 是200个CString类当实体对象组成的数组,而不是ip有200个字符空间……所以要使用上面的方法……
在这种情况下当然不行
除非你是用char ip[200];CString是一个对象,需要初始化,构造函数的调用
如果memset了,那这个对象就未经过初始化了
你上面说的CString ip[200]并不是字符串数组,这个是个CString的对象数组。CString是个封装了字符串的对象
CString ip[200];
for(int i=0;i<200;i++)
{
ip[i].empty();
}
CString ip[200];为字符串数组
CString ip;为字符串
char szIp[200];为字符数组
CString *ip;
ip=new CString[200];
for (int i=0; i<200; i++)
{
ip[i].empty();
}
{
ip[i].Empty();
}
CString 还不是一个Const char* 类型的变量吗?CString 的类型定义上不就是这么写的吗?
============
CString可不是const char *,CString是MFC提供的对字符串处理的类,和char *的差别可不是一般的大。
先定义字符串数组CString ip[200];
然后使用中用IP字符串数组暂存一下一些字符串,
再下一次循环使用前,先清空原已存储的IP字符串数组,重复使用IP数组空间。
由于下一循环使用时,涉及的字符串数量有可能比上一次使用的数组有可能少,也有可能多,因此需要将201个IP字符串空间都清空一下。这样,二楼的CString ip[200]={_T("")};就不可行了。
如果用for (int i=0; i<200; i++)
{
ip[i].Empty();
}
那效率太低了,如果循环的次数大的话,或有二层循环嵌循环,那对程序执行速度影响太大。因此征求更有效率的清空方法。
但是CString对象构造的时候,应该是被清空了。。
ip[i].Empty();} 这个我查了一下内存,原来是把CString里面指向堆里的内容先 delete,操作上可能会慢上些.debug 了一下一个 CString 赋值的操作
CString str = "123";
CString str = "1234567890"; 这时由于长度变得更长了,CString的赋值操作函数会先delete原来的"123"处的内存,再重新new一个新的11个位置的内存来放新数据.之后再赋值 str = "abcd"; 由于长度小于之前的长度,str不会再次执行delete 与 new 的操作,只会在原来的地方写入 abcd\0 可以查到内存中的数据为 abcd\067890所以如果楼主想效率高的话,最好是一开始把CString 的长度设得大一些,避免以后再重复申请内存,然后下次直接赋值即可,不用再清零了.
别学坏了
他后面说的有问题
这个不是CString有多大、是不是固定大小的问题,
清空一个类、结构
不需要知道有多大,sizeof就可以,
大小是固定的,在编译的时候就确定了
不用memset是因为类对象是初始化一般都是他的构造函数做的
=======
CString的对象大小应该是不固定的吧,CString a;的大小
和a="kdjfkldjfkldj";的大小应该是不一样的吧。
CString a;
int iSize1 = sizeof(a);
a = "aadfadffadfasd"
int iSize2 = sizeof(a);
永远是4看过CString 的代码,他里面就是一个指向堆的字符数组的指针,所以大小是4.
大小不同的是在堆里面.不同的值,就不同大小了.
我DEBGU过,查过内存的.
例如下面的代码. CString str = "123456789";
str = "abc";
MessageBox(str); //会输出 abc ,后面的内容没有影响
MessageBox((LPCTSTR)(str) + 4); //会输出56789,因为后面的内容还在
第一次循环得到四个字符串,如
IP[0]="aaa1"
IP[1]="aaa2"
IP[2]="aaa3"
IP[3]="aaa4"
然后程序有个显示动作,在界面上显示这四个值,其它IP[N]都是空字符。
第二次循环得到两个字符串
IP[0]="b1"
IP[1]="b2"
然后程序有个显示动作,这时,在界面上会下面显示四个值,其它IP[N]都是空字符。
IP[0]="b1"
IP[1]="b2"
IP[2]="aaa3" (这是因为没有清空的结果)
IP[3]="aaa4" (这是因为没有清空的结果)
所以,这个结果不是想要的,原来想要的显示结果如下
IP[0]="b1"
IP[1]="b2"
所以高效地清空IP[]字符串数组就非常重要了。
CString str[200];
LARGE_INTEGER liFreq,liStart,liEnd;
int i;
for (i=0;i<200;i++) //先赋值,分配一下内存
{
str[i] = "abc";
} QueryPerformanceFrequency(&liFreq);
QueryPerformanceCounter(&liStart);
for (i=0;i<200;i++)
{
str[i].Empty();
}
QueryPerformanceCounter(&liEnd);
double fCount = liEnd.QuadPart - liStart.QuadPart;
TRACE("直接Empty用时____%.10f 秒\n",fCount/liFreq.QuadPart); QueryPerformanceCounter(&liStart);
for (i=0;i<200;i++)
{
str[i] = "";
}
QueryPerformanceCounter(&liEnd);
fCount = liEnd.QuadPart - liStart.QuadPart;
TRACE("写0清零用时______%.10f 秒\n",fCount/liFreq.QuadPart);用写0来清吧,测试过了一下,输出如下.
直接Empty用时____0.0009060139 秒
写0清零用时______0.0000265256 秒楼主,你说用for循环会慢,之前有朋友说过改为用while(--i)这类型的会快一些,但我度测过,while与for循环都是差不多的时间.我也没有深入去看汇编了.