【问题标题】:Difference between a C++ string and a C-string ( .c_str() ) [duplicate]C ++字符串和C字符串( .c_str() )之间的区别[重复]
【发布时间】:2011-04-21 06:29:54
【问题描述】:

可能的重复: Why does std::string not provide a conversion to const char*? Why doesn't std::string provide implicit conversion to char*?

 case 1 :
 void readFile ( const string& inputfile ) {
     ifstream in ( inputfile  );
 }

 case 2:
 void readFile ( const string& inputfile ) {
     ifstream in ( inputfile . c_str() );
 }

当然,我知道如何使用必需参数调用ifstream,但是C++ 字符串和以空字符结尾的字符序列(C 字符串).c_str() 之间的真正区别是什么?**

我认为自动类型转换应该发挥作用,即自动将 C++ 字符串转换为 .c_str()。我错了吗?

案例 1 出错,案例 2 工作正常。是否可以使用static_cast<> 将案例 1 转换为案例 2?

【问题讨论】:

标签: c++ c


【解决方案1】:

std::string 是一个存储字符串的类,恰好是在 C++ 中处理字符串的标准方式,它应该如何实现以及它应该如何使用内存并不是 C++ 标准明确定义的,它只是定义它的 API。不幸的是std::ifstream 出现在std::string 标准化之前,所以它的接口使用了旧的C 字符串。

C 字符串只是 char *(指向 char 的指针),它遵循 C 标准强加的某些约定。即当指针指向的数据恰好以'\0'结尾时,可以认为是字符串。因此,如果我不按照惯例使用char *(通过不使用'\0' 遵循我的相关数据),即使它是正确的类型,它也不能被视为C 字符串。在需要 C 字符串的标准函数中使用这样的指针肯定是错误的。

调用.c_str() 将给出一个const char * 指针,该指针可用作C 字符串,正如C 标准定义的那样。 .c_str()返回的指针与std::string对象的指针不同,C++标准也没有要求,但返回的C字符串属于C++对象并由C++对象管理。

【讨论】:

    【解决方案2】:

    std::string 无法转换为 const char*,因此您必须调用 .c_str() - 此处没有显式转换可以帮助您。

    【讨论】:

      【解决方案3】:

      C++ 字符串和以空字符结尾的字符序列 (C-string) .c_str() 之间的真正区别是什么?

      一个 C++ std::string 对象封装:

      • char 数组存储语义(可能是文本)值
        • 某些实现将短文本字符串直接存储在 std::string 对象中
        • 否则堆内存通常用于存储实际的字符串内容
      • 指向字符数组的指针(可能通过其他控制结构)
      • std::string::size_type变量记录字符串的大小和容量
      • 可能还有其他事情

      在实践中,std::string 的文本数据——无论是在内部缓冲还是保存在堆上,在现实世界的实现中极有可能存储为 C 字符串 ASCIIZ 值,这样c_str() 可以很简单返回它的地址,但这不是标准要求的。一个近乎最坏的情况(就在可信度的范围内)场景是字符串有第二个指针,c_str() 将非 NUL 终止的字符串内容复制到它 NUL 终止的新分配的堆区域中。唯一看起来有益的情况是 NUL 本身将字符串倾斜到某个容量边界,例如从短字符串优化/内部缓冲区到堆,或从 1 页堆内存到 2、2 到 3 等。 ..

      我认为自动类型转换应该发挥作用,即自动将 C++ 字符串转换为 .c_str()。我错了吗?

      是的,它可以做到,但不安全(请参阅链接的可能重复问题)。

      案例 1 出错,案例 2 工作正常。是否可以使用 static_cast 将案例 1 转换为案例 2?

      static_cast<> 无法将 std::string 对象转换为 const char*... 请记住字符串对象本身包含所有其他内容,并且通常(始终适用于除最小字符串之外的所有字符串)只有指向实际文本数据的指针。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-18
        • 1970-01-01
        • 1970-01-01
        • 2017-01-29
        • 1970-01-01
        • 2020-09-07
        • 1970-01-01
        相关资源
        最近更新 更多