string类的data()与c_str()的区别

来源:互联网 发布:java 数组去重效率 编辑:程序博客网 时间:2024/06/06 01:32

 cout<<"\n========================"<<endl;
 //s) c_str() //将内容以C_string返回
 {
        string myStr1("Hello--------");
        string myStr2("world!\n");
  const char* pStr=(myStr1+myStr2).c_str();
  printf(pStr);
  printf("%d\n",pStr[strlen(pStr)]);
  myStr1+="DEF\n";
  printf(myStr1.c_str());

 }
 //t) data() //将内容以字符数组形式返回
 {
        string myStr("Hello world!\n");
  const char* pStr=myStr.data();
  printf(pStr);
  printf("%d\n",pStr[strlen(pStr)]);
 }
 cout<<"\n========================"<<endl;

========================
Hello--------world!
0
Hello--------DEF
Hello world!
0

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



请问string类的data()与c_str()的区别 [问题点数:20分,结帖人Dic4000]

收藏
楼主 发表于: 2007-01-20 01:32:56
有人说:
     data只是返回原始数据序列,没有保证会用traits::eos(),或者说'\0'来作字符串结束.
     c_str是标准的做法,返回的char* 一定指向一个合法的用'\0'终止的C兼容的字符串。   
但我写了个测试,发现转换后的字符串末尾都有'\0',请问这两个成员函数到底有什么区别?应该在哪种场合下用哪一个?
string s("123456");
const char *p=s.c_str();
const char *q=s.data();
int d;

for(int i=0;i<=s.size();i++) {d=*(p+i);cout<<d<<endl;}//最后一次输出的是0.
cout<<endl;
for(int i=0;i<=s.size();i++) {d=*(q+i);cout<<d<<endl;}//最后一次输出的也是0.
  • <iframe width="200" height="22" align="center,center" id="iframeu1636200_0" src="http://pos.baidu.com/vcem?rdid=1636200&amp;dc=2&amp;di=u1636200&amp;dri=0&amp;dis=0&amp;dai=2&amp;ps=981x396&amp;dcb=BAIDU_SSP_define&amp;dtm=HTML_POST&amp;dvi=0.0&amp;dci=-1&amp;dpt=none&amp;tsr=0&amp;tpr=1472608531471&amp;ti=%E8%AF%B7%E9%97%AEstring%E7%B1%BB%E7%9A%84data()%E4%B8%8Ec_str()%E7%9A%84%E5%8C%BA%E5%88%AB-CSDN%E8%AE%BA%E5%9D%9B-CSDN.NET-%E4%B8%AD%E5%9B%BD%E6%9C%80%E5%A4%A7%E7%9A%84IT%E6%8A%80%E6%9C%AF%E7%A4%BE%E5%8C%BA&amp;ari=2&amp;dbv=0&amp;drs=3&amp;pcs=1371x643&amp;pss=1371x7834&amp;cfv=20&amp;cpl=2&amp;chi=2&amp;cce=true&amp;cec=utf-8&amp;tlm=1472608531&amp;rw=643&amp;ltu=http%3A%2F%2Fbbs.csdn.net%2Ftopics%2F100038356&amp;ecd=1&amp;psr=1371x857&amp;par=1371x739&amp;pis=-1x-1&amp;ccd=24&amp;cja=true&amp;cmi=4&amp;col=zh-CN&amp;cdo=-1&amp;tcn=1472608532&amp;qn=559415ed0bc7c000&amp;tt=1472608531117.483.1824.1824" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" vspace="0" hspace="0" style="margin: 0px; border: 0px currentColor; border-image: none; vertical-align: bottom;" allowtransparency="true"></iframe>
  • 创投前沿技术分享会
  • <iframe width="200" height="22" align="center,center" id="iframeu1636204_0" src="http://pos.baidu.com/vcem?rdid=1636204&amp;dc=2&amp;di=u1636204&amp;dri=0&amp;dis=0&amp;dai=3&amp;ps=981x904&amp;dcb=BAIDU_SSP_define&amp;dtm=HTML_POST&amp;dvi=0.0&amp;dci=-1&amp;dpt=none&amp;tsr=0&amp;tpr=1472608531471&amp;ti=%E8%AF%B7%E9%97%AEstring%E7%B1%BB%E7%9A%84data()%E4%B8%8Ec_str()%E7%9A%84%E5%8C%BA%E5%88%AB-CSDN%E8%AE%BA%E5%9D%9B-CSDN.NET-%E4%B8%AD%E5%9B%BD%E6%9C%80%E5%A4%A7%E7%9A%84IT%E6%8A%80%E6%9C%AF%E7%A4%BE%E5%8C%BA&amp;ari=2&amp;dbv=0&amp;drs=3&amp;pcs=1371x643&amp;pss=1371x7834&amp;cfv=20&amp;cpl=2&amp;chi=2&amp;cce=true&amp;cec=utf-8&amp;tlm=1472608531&amp;rw=643&amp;ltu=http%3A%2F%2Fbbs.csdn.net%2Ftopics%2F100038356&amp;ecd=1&amp;psr=1371x857&amp;par=1371x739&amp;pis=-1x-1&amp;ccd=24&amp;cja=true&amp;cmi=4&amp;col=zh-CN&amp;cdo=-1&amp;tcn=1472608532&amp;qn=85a2f14c333ac69e&amp;tt=1472608531117.487.1795.1795" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" vspace="0" hspace="0" style="margin: 0px; border: 0px currentColor; border-image: none; vertical-align: bottom;" allowtransparency="true"></iframe>
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    回复次数:20
    #1 得分:0回复于: 2007-01-20 02:07:48
    data指向自己 ;修改data就是修改自己;
    c_str指向它所指的对象;修改了它,但不修改它所指的对象;

    形象点, data是自身,c_str是镜子.
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #2 得分:0回复于: 2007-01-20 02:32:01
    两个都不能修改,以下是两个函数的声明
    const char *data( ) const;

    const char *c_str( ) const;
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #3 得分:0回复于: 2007-01-20 10:24:25
    我也不是很清楚,感觉有点差不多。
    c_str()不可能是镜子,镜子的成本太高了。
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #4 得分:0回复于: 2007-01-20 13:08:27
    “没有保证会用traits::eos(),或者说'\0'来作字符串结束.”
    并不是说一定不以\0结束。在很多stl版本中data和c_str是完全相同的。
    但是,是“很多”,不是“所有”
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #5 得分:0回复于: 2007-01-20 13:20:48
    建议楼主看看C++03,上面有详细的描述.
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #6 得分:5回复于: 2007-01-20 13:35:24
    我的理解,不知道对不对:

    string s("123456");
    ------
    “123456”为字符串字面值,以null空字符结束,所以s本身的后面就有个'\0'字符吧
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #7 得分:0回复于: 2007-01-20 14:04:08
    一向都是用c_str(), 没用过data()
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #8 得分:0回复于: 2007-01-20 17:22:32
    未之闻也,学习
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #9 得分:5回复于: 2007-01-20 18:01:24
    data 是字符数组,里面有'\0'当然也不会删掉string的原则就是无视这个c字符串规则.

    c_str 是产生c字符串,也就是即使没有'\0'结尾,她也会添加一个.

    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #10 得分:0回复于: 2007-01-20 19:24:01
    C/C++高级群20641933
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #11 得分:0回复于: 2007-01-20 19:37:12
    没用过,感觉因该没什么区别吧
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #12 得分:0回复于: 2007-01-20 20:11:14
    说是这样说,可是有的实现是一样的
          //....
          // This file is part of the GNU ISO C++ Library.....
          //....
          /**
           *  @brief  Return const pointer to null-terminated contents.
           *
           *  This is a handle to internal data.  Do not modify or dire things may
           *  happen.
          */
          const _CharT*
          c_str() const { return _M_data(); }

          /**
           *  @brief  Return const pointer to contents.
           *
           *  This is a handle to internal data.  Do not modify or dire things may
           *  happen.
          */
          const _CharT*
          data() const { return _M_data(); }
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #13 得分:0回复于: 2007-01-21 13:32:46
    没用过data()
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #14 得分:5回复于: 2007-01-21 14:35:14
    从C++标准上的解释来看,只有一点区别:
    c_str()返回的指针保证指向一个size() + 1长的空间,而且最后一个字符肯定"\0";
    而data返回的指针则保证指向一个size()长度的空间,有没有null-terminate不保证,可能有,可能没有,看库的实现了。
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #15 得分:0回复于: 2007-01-21 14:48:49
    支持如下: 
    steedhorse(晨星) ( ) 信誉:141    Blog  2007-01-21 14:35:14  得分: 0  
     
     
       从C++标准上的解释来看,只有一点区别:
    c_str()返回的指针保证指向一个size() + 1长的空间,而且最后一个字符肯定"\0";
    而data返回的指针则保证指向一个size()长度的空间,有没有null-terminate不保证,可能有,可能没有,看库的实现了。
      
     
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #16 得分:0回复于: 2007-01-22 12:54:50
    感觉确实有些多余.
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #17 得分:0回复于: 2007-01-24 09:51:16
    哪位老大给个例子最好不过了
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #18 得分:5回复于: 2007-01-24 10:31:54
    string中的数据并没有保证被存储在独立的一块连续内存中,string的内部表示形式并没承诺以一个null字符结束。这解释了string 的成员函数c_str存在的原因,它返回一个按C风格设计的指针,指向string的值。因此我们可以这样传递一个string对象s给这个函数
    void doSomething(const char *pString);
    即使是字符串的长度为0,它都能工作。data并没有这个保证(也就是说返回字符串一定会以null结尾)

    但是在实际编译器中,两者返回结果是相同的
    以下是vs7.1下的两个函数的源码,可以清楚看到,data函数内部调用的c_str()
    const _Elem *c_str() const
    { // return pointer to null-terminated nonmutable array
    return (_Myptr());
    }

    const _Elem *data() const
    { // return pointer to nonmutable array
    return (c_str());
    }
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #19 得分:0回复于: 2007-01-24 21:36:20
    mark
    对我有用[0]丢个板砖[0] 引用 | 举报 |
    编辑删除
    管理
    #20 得分:0回复于: 2011-11-18 18:18:30
    学习了
    0 0
    原创粉丝点击