CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

string str = "" 是不是相当于没有初始化

楼主YuriOU()2005-12-20 13:02:48 在 C/C++ / C++ 语言 提问

#include   <string>  
  #include   <iostream>  
  using   namespace   std;  
  --错误:  
  void   main()  
  {  
      string   aa   =   "";       --初始化为""  
      strcpy((char   *)aa.c_str(),"djsfsad");     --出现错误  
      cout   <<   aa   <<   endl;  
  }  
  --正确:  
  void   main()  
  {  
      string   aa   =   "   ";       --随便初始化为空格  
      strcpy((char   *)aa.c_str(),"djsfsad");     --正确通过  
      cout   <<   aa   <<   endl;  
  }  
   
  是不是string   aa   =   "";还是没有为aa变量分配空间,而aa   =   "   ";就有  
  还是函数strcpy的问题?  
  假如现在必须用类似strcpy这样写法(sprintf和memcpy也出现同样问题),是不是aa不能初始化为""?  
  问题点数:30、回复次数:38Top

1 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2005-12-20 13:19:45 得分 0

不是没有初始化,而是初始化为NULL啊。。  
  strcpy不接受dest为NULLTop

2 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2005-12-20 13:20:30 得分 0

上面说错,应该是初始化为"\0"Top

3 楼zhousqy(标准C匪徒)(甩拉,甩拉)回复于 2005-12-20 13:25:43 得分 0

这样拷贝能行吗?有内存访问的问题的阿Top

4 楼piaochen_2002(执子之手,与子偕老!)回复于 2005-12-20 13:35:25 得分 0

string   aa   =   "";       aa为NULLTop

5 楼xianshiqi(日出西山)回复于 2005-12-20 13:38:12 得分 0

找不到aa在何处结束Top

6 楼useresu(俗人)(灌水是我无言的抗议)回复于 2005-12-20 13:47:44 得分 0

上面说错,应该是初始化为"\0"  
  //////////////  
  string里哪有\0?Top

7 楼useresu(俗人)(灌水是我无言的抗议)回复于 2005-12-20 13:52:05 得分 0

string   aa;和  
  string   aa   =   "";    
  是一样的,  
  都是初始化为空串,  
   
  但是要用strcpy之前要先分配内存,  
   
  而且即使分配了内存,也不能用c_str()做为dest  
   
  c_str()得到的是const指针  
   
  Top

8 楼useresu(俗人)(灌水是我无言的抗议)回复于 2005-12-20 13:54:03 得分 0

--正确:  
  void   main()  
  {  
      string   aa   =   "   ";       --随便初始化为空格  
      strcpy((char   *)aa.c_str(),"djsfsad");     --正确通过  
      cout   <<   aa   <<   endl;  
  }  
  ///////////////////////////  
  表示怀疑  
   
  直接  
  aa   =   "djsfsad";不就可以吗?  
   
  楼主的做法纯是为了测试string的多种用法?Top

9 楼YuriOU()回复于 2005-12-20 13:57:26 得分 0

只要string   aa   =   "   ";  
  就可以strcpy((char   *)aa.c_str(),"djsfsad");     --正确通过  
  Top

10 楼windking21(想玩玩WOW 真的那么难吗)回复于 2005-12-20 13:58:48 得分 0

这个是用C的表现形式来写的string   --->aa.c_str()为的可以使用strcpy  
  Top

11 楼healer_kx(甘草(楼主揭贴吧,我们这些上班灌水的也不容易))回复于 2005-12-20 14:01:42 得分 0

std::string不存在所谓的初始化。  
   
  std::string   a;就已经是初始化完毕的了。Top

12 楼YuriOU()回复于 2005-12-20 14:02:48 得分 0

是有特殊用法才这样写的。  
  那各位定义string类型的时候是不是都不需要初始化,因为  
  string   aa;和string   aa   =   "";   是一样的  
   
  ???Top

13 楼YuriOU()回复于 2005-12-20 14:09:30 得分 0

 
  std::string   aa;就已经是初始化完毕的了。  
  //////////////////////  
   
  有没有什么函数可实现把值赋给aa(除了aa="asdjff"之外);而不需要先对aa初始赋值?Top

14 楼sinall()回复于 2005-12-20 14:11:25 得分 0

basic_string::c_str  
  const   E   *c_str()   const;  
   
  char   *strcpy(   char   *strDestination,   const   char   *strSource   );  
  ——————————————————————————————————————————  
  所以,(char   *)aa.c_str()最好不要也没有必要作为strcpy的strDestination参数。  
  使用aa   =   "djsfsad"即可。  
   
  再者,楼主需要明白strcpy的用法,strDestination必须要有足够的空间容纳strSource。  
  The   strcpy   function   copies   strSource,   including   the   terminating   null   character,   to   the   location   specified   by   strDestination.   No   overflow   checking   is   performed   when   strings   are   copied   or   appended.   The   behavior   of   strcpy   is   undefined   if   the   source   and   destination   strings   overlap.  
   
  《Effective   STL》条款13:尽量使用vector和string来代替动态分配的数组  
  楼主可以考虑使用vector<char>   aa来代替string   aa,&aa[0]既是char*。  
  同理要使用strcpy的话,aa必要要有足够的空间。  
  Top

15 楼YuriOU()回复于 2005-12-20 14:15:04 得分 0

不知道string   aa   =   "   ";已经分配的多大空间  
   
  现在是strcpy((char   *)aa.c_str(),"djsfsadafdfdsfadsfdsffewquiorjkasdjfoisudfoid...");  
  可以往aa拷贝很多的字符。Top

16 楼rbofnjtu(诱因)回复于 2005-12-20 14:26:48 得分 0

回复人:   useresu(俗人)(灌水是我无言的抗议)   (   )   信誉:106     2005-12-20   13:52:00     得分:   0      
     
     
        string   aa;和  
  string   aa   =   "";    
  是一样的,  
  都是初始化为空串,  
   
  但是要用strcpy之前要先分配内存,  
   
  而且即使分配了内存,也不能用c_str()做为dest  
   
  c_str()得到的是const指针  
   
  ----------------------------------------------------------------  
  这里用了一个强制类型转换(char*)aa.c_str()将dest变为非const了,所以是可以的。真正的原因在于强制类型转换只是得到了一个地址,而这个地址后可用的合法空间的大小取决于之前的初始化。所以string   aa=""时,aa是一个空串,strcpy没有讲任何内容拷贝到aa中;当string   aa="   "时,aa占用一个字符的空间,这时只能将"djsfsad"中的第一个字符"d"拷贝过去,输出结果就是d,当aa中本来具有的字符串的长度与"djsfsad"的长度相等,都为7时(比如aa   =   "1234567"),能够正确输出"djsfsad";当aa的长度大于"djsfsad"的长度时,输出结果为"djsfsad***",这里的"***"是指   aa的长度减去"djsfsad"的长度   个空格。  
  以上结果在.net下测试过  
       
     
  Top

17 楼rbofnjtu(诱因)回复于 2005-12-20 14:28:49 得分 0

还是sinall()   讲得更有条理,我的解释有点啰嗦了^_^Top

18 楼sinall()回复于 2005-12-20 14:31:41 得分 0

不知道string   aa   =   "   ";已经分配的多大空间  
  ————————————————————————————————————————————  
  aa.size();Top

19 楼YuriOU()回复于 2005-12-20 14:35:39 得分 0

但是我在vc6下  
  string   aa   =   "   ";  
  strcpy((char   *)aa.c_str(),"djsfsadafdfdsfadsfdsffewquiorjkasdjfoisudfoid...");  
   
  按你所说的应该是输出d字符  
  实际上输出了djsfsadafdfdsfadsfdsffewquiorjkasdjfoisudfoid...Top

20 楼YuriOU()回复于 2005-12-20 14:39:02 得分 0

应该最多可以输出32个字符,而不是1个。  
  string   aa   =   "   ";  
  strcpy((char   *)aa.c_str(),"djsfsadafdfdsfadsfdsffewquiorj1");  
  肯定是没有问题的  
   
  但是超过32个就有问题了Top

21 楼sinall()回复于 2005-12-20 14:48:35 得分 0

套用新东方老罗的一句话:用错误推理得出正确答案。  
   
  把你的aa.size()打出来看看。  
   
  为什么输出会对呢?是因为strcpy做了它该做的事情——这才是问题真正可怕的地方。  
  strcpy不管三七二十一,只管拷贝……Top

22 楼rbofnjtu(诱因)回复于 2005-12-20 15:37:53 得分 0

当strDestination没有足够的空间容纳strSource时,看来结果是undefined的。我又试了几次,不同的情况下结果都不一样,没什么规律。总之,当strDestination没有足够的空间容纳strSource时,相当于对未合法分配的内存空间进行操作(有点类似于野指针导致的后果),strcpy是不对所操作的空间进行检查的,所以,不要那么用才是最好的办法^_^  
  另外刚才debug的时候发现一个有趣的现象,当字符串的长度不超过15时,是存放在string对象的_Bx._Buf中的,这个_Buf的长度只有16。当字符串的长度在16以上时,是存放在string._Bx._Ptr指向的一个地址空间的,不知道为什么是这样,有什么特别的原因吗?哪位高人给解说一下?另外我用的是.net环境编译的,这样的现象是VC特有还是C++的标准(有人说VC自带的STL比较烂)Top

23 楼dragonzxh(河马MiaMia~柯奶奶和黑爷爷的儿子叫柯南...~)回复于 2005-12-20 15:43:34 得分 0

STL对string的优化吧。。。。先构造16的字符串,超过则再构造,不超过就   16个。好像是的。乱说的Top

24 楼v41dugu(一步一生)回复于 2005-12-20 16:24:20 得分 0

好象是12个吧。。。呵呵   也不是很清楚   不过这个不重要   你知道string   str="";str里有一个元素是'\0'就对了Top

25 楼all4u(东方欲晓)回复于 2005-12-20 16:44:12 得分 0

用vector<char>代替string就很爽么?感觉越来越麻烦了。Top

26 楼YuriOU()回复于 2005-12-20 16:57:23 得分 0

没别的好方法,只能先进行空间分配,比如预存入500个字符,  
  那么:  
  void   main()  
  {  
  string   aa   =   "";  
  aa.resize(500/16+1);  
  strcpy((char   *)aa.c_str(),"djsfsadafdfdsfadsfdsffeasdfdwquiorjkasdjfoisudfoid...");  
  cout   <<   aa   <<   endl;  
  }Top

27 楼huangjianmin(撒旦使者)回复于 2005-12-20 21:19:43 得分 0

在你们讨论完成前做个记号,各位该说的能说的都差不多了Top

28 楼useresu(俗人)(灌水是我无言的抗议)回复于 2005-12-20 22:00:29 得分 0

没看楼上们的回复   ,  
   
  所以我以下说的可能是废话  
   
  但是楼主所谓的正确通过  
   
  只是一种侥幸  
   
  不能作为正确的理由,  
   
  你这样只是对字符串指针赋了值,  
   
  然后侥幸没有出错误,  
   
  这种做法绝对是错误的  
   
  一定要先申请足够的空间Top

29 楼useresu(俗人)(灌水是我无言的抗议)回复于 2005-12-20 22:03:09 得分 0

 
   
  用vector<char>代替string就很爽么?感觉越来越麻烦了。  
  //////////////////////////  
  扫了一眼,就看到这个了,  
   
  vector代替sting   ,不可取,  
   
  sting   还是有其特殊性的.  
   
  重申上述观点:  
  指针操作错误并不一定就出错  
   
  但是你是在制造错误的隐患  
   
  Top

30 楼Seben(批着狼皮的羊)回复于 2005-12-20 23:39:57 得分 0

basic_string::c_str的定义为:  
        const   E   *c_str()   const  
   
  STL做了它该做的事情,就是返回一个const   char   *   (这里显然E表示char),const   char   *   表示的是:这个一个const,你可以读取,但是不可以赋值;  
   
  strcpy也做它该做的事情,就是把一个const   char   *   复制到一个char   *;  
   
  你的错误在于,把aa.c_str()做了一个强制类型转换,从而违背了STL的使用规范,这可以从aa.size()   ==   1得到证明。  
   
  使用strcpy,必须开辟足够的内存区,正确的做法应该是:  
          {  
                    char   aa[BUF_SIZE]   =   {0};     //   or   aa   =   {"\0"}  
  strcpy(aa,   "djsfsad");  
  cout   <<   aa   <<   endl;  
          }  
   
  另外:  
  (1)'0'   表示ASCII码的可打印字符0,实际上它的值不是0,这个可以用以下代码验证:  
      char   ch   =   '0';  
      int   ch_int   =   (int)ch;  
      cout   <<   ch_int   <<   endl;  
   
        '\0'   才表示真正的0值,可以这样验证  
      char   ch   =   '\0';  
      int   ch_int   =   (int)ch;  
      cout   <<   ch_int   <<   endl;  
   
  (2)   "\0"没有太多的意义,因为双引号"abcd"的内存表示为:{'a','b','c','d','\0'},也就是说双引号会自动添加一个0值在字符串的后面。  
   
  (3)   string   aa   =   "";       aa为NULL     这个说法不对,NULL表示没有赋值的指针,NULL是一个宏,它在VC6下的定义就是0;""并不是NULL,可以参考(2)  
   
  (4)   (char*)variable是一种C的类型转换模式,在C++中强烈不推荐使用;STL是基于C++的,它有它的基本思想,【用vector<char>代替string就很爽么?感觉越来越麻烦了。】这种说法也是不鼓励的。  
  Top

31 楼Seben(批着狼皮的羊)回复于 2005-12-20 23:43:29 得分 0

应该最多可以输出32个字符,而不是1个。  
  string   aa   =   "   ";  
  strcpy((char   *)aa.c_str(),"djsfsadafdfdsfadsfdsffewquiorj1");  
  肯定是没有问题的  
   
  但是超过32个就有问题了  
  ----------------  
   
  cout跟size没有关系的。输出字符串的时候,cout看到的是一个char   *或const   char   *,它会输出直到遇到'\0'。  
  Top

32 楼YuriOU()回复于 2005-12-21 09:08:22 得分 0

感谢楼上各位的讨论  
  其实我这样写的目的是为了动态实现。  
  //对应数据库的各个字段,可能非常多  
  class   struct_LbasServ{  
  public:  
    string   str_lbasmonthlyquota;  
    string   str_lbasservducity;  
    string   str_lbasservdusplineno;  
    string   str_lbasservducustname;  
    string   str_lbasservduaddr;  
    string   str_lbasacctermcount;  
   
  struct_LbasServ()  
  {  
    str_lbasmonthlyquota="";  
    str_lbasservducity="";  
    str_lbasservdusplineno="";  
    str_lbasservducustname="";  
    str_lbasservduaddr="";  
    str_lbasacctermcount="";  
  }  
  };  
   
  void   main()  
  {  
    struct_LbasServ   r_LbasServ;  
  //防止内存泄漏,先申请空间  
    r_LbasServ.str_lbasmonthlyquota.resize(512);  
    r_LbasServ.str_lbasservducity.resize(512);  
    r_LbasServ.str_lbasservdusplineno.resize(512);  
    r_LbasServ.str_lbasservducustname.resize(512);  
    r_LbasServ.str_lbasservduaddr.resize(512);  
    r_LbasServ.str_lbasacctermcount.resize(512);  
  //定义成二维数据或更多维  
    char*   feaParm[][2]   =   {  
      {(char   *)r_LbasServ.str_lbasmonthlyquota.c_str() ,   "MONTHLY_QUOTA"   },  
      {(char   *)r_LbasServ.str_lbasservducity.c_str() ,   "015" },  
      {(char   *)r_LbasServ.str_lbasservdusplineno.c_str() ,   "014" },  
      {(char   *)r_LbasServ.str_lbasservducustname.c_str() ,   "003" },  
      {(char   *)r_LbasServ.str_lbasservduaddr.c_str() ,   "002" },  
      {(char   *)r_LbasServ.str_lbasacctermcount.c_str()   ,   "ACC_TERM_COUNT"},  
  };  
  //伪动态处理  
    for(int   i=0;   i   <   sizeof(feaParm)/sizeof(char   *)/2;   i++){  
      //把feaParm[i][1])拿出来做一系列处理(步骤很多),把最后处理的值赋值给对应的feaParm[i][0]中的字段。  
      //各位帮忙想想能不能在这里实现给各个字段申请空间也就是resize操作  
      strcpy(feaParm[i][0],结果值);  
    }  
  }  
   
  由于struct_LbasServ类中的字段非常多(上面没有全部列出来),那么对各个字段做同样的处理,如果没有写成动态,程序非常庞大而且也不易查看,所有才想出这样写的,不知道各位高手还有没有别的好方法。Top

33 楼useresu(俗人)(灌水是我无言的抗议)回复于 2005-12-21 12:46:11 得分 0

首先数据库的字段长度一般固定  
   
  在这种情况下,一般用定长char数组是最好的选择  
   
  new和delete绝对影响效率  
   
  但是用string实现也无可后非,  
   
  但是你用string就都用string实现好了,  
   
  完全可以省去strcpy(),  
   
  偏偏你用了char   *,  
   
  你用char   *   也可以,  
   
  但记得strcpy之前,  
   
  要先sizeof一下"结果"的长度,  
   
  然后给feaParm[i][0]释放原来空间,重新申请足够的空间  
   
  才能strcpy  
   
   
   
  Top

34 楼useresu(俗人)(灌水是我无言的抗议)回复于 2005-12-21 12:47:22 得分 0

这是用strcpy最基本的思路,  
   
  如果你不清楚strcpy,  
   
  最好先msdnTop

35 楼tyfool(台风)回复于 2005-12-21 18:11:38 得分 0

string   aa="   ";    
   
                  strcpy((char   *)aa.c_str(),   "asdfasdfasdf");  
   
                  cout   <<   aa   <<   endl;  
                  cout   <<   aa.size()   <<   endl;  
   
  =====================  
  我得到的输出是  
  a  
  1  
  不是asdfasdfasdfTop

36 楼deping_chen(小平)回复于 2005-12-21 20:54:15 得分 0

string   aa   =   "";       --初始化为""  
      strcpy((char   *)aa.c_str(),"djsfsad");     --出现错误  
   
  不要混用C和C++字符串。  
  直接写string     aa   =   "djsfsad";   不好吗?Top

37 楼Seben(批着狼皮的羊)回复于 2005-12-21 21:37:10 得分 0

//防止内存泄漏,先申请空间  
    r_LbasServ.str_lbasmonthlyquota.resize(512);  
   
  这样确实不会内存泄漏了,不过std::string本来就考虑了内存处理,你只用string的话,是不会内存泄漏的!  
   
  问题是数据可能会溢出。  
   
  这种问题,可能某些运行侥幸结果没有错,但是一旦出现问题,调试都调试不出来。  
   
  建议你先系统学习一下STL。Top

38 楼Seben(批着狼皮的羊)回复于 2005-12-21 21:43:10 得分 0

已经解释过了,  
   
  (char   *)r_LbasServ.str_lbasmonthlyquota.c_str()    
   
  是不对的,至少你还不适合使用这样的用法。如果我没错的话,你应该是STL的初学者,那么我的建议是,绝对不要对STL里面的函数或对象进行强制类型转换!如果你直接使用STL的函数,而compiler报错的话,就去查msdn。Top

相关问题

  • 如果初始化sprinf(m_str,"%s","Test")就出错?
  • 请问怎么初始化一个二维String数组?
  • 初始化非string型变量的问题?
  • 关于connection string属性 未初始化的问题
  • 我定义了一个array of string,初始化的时候报错
  • 怎样初始化类中的static vector<string> vstr;
  • mysql初始化
  • list初始化
  • 初始化
  • 如何对ComboBox进行初始化呀,错误IDC_Combo01::AddString(str)为什么不行

关键词

  • .net
  • 字符
  • 内存
  • 指针
  • lbasserv
  • aa
  • djsfsad
  • 初始化
  • strcpy
  • 长度

得分解答快速导航

  • 帖主:YuriOU

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo