C ++字符串和C字符串之间的区别(.c_str())

时间:2011-04-21 06:29:54

标签: c++ c

  

可能重复:   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-string).c_str()之间的真正区别是什么? **

我认为自动类型转换应该完成它的工作,即自动将C ++字符串转换为.c_str()。我错了吗?

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

3 个答案:

答案 0 :(得分:5)

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

C字符串只是char *(指向char的指针),遵循C标准规定的某些约定。也就是说,当指针指向的数据恰好以'\0'结束时,它可以被认为是一个字符串。因此,如果我不按惯例所说的那样使用char *(通过不使用'\0'跟随我的相关数据),则不能将其视为C字符串,即使它是正确的类型。在期望C字符串的标准函数中使用这样的指针肯定是一个错误。

调用.c_str()将提供一个可用作C字符串的const char *指针,正如C标准所定义的那样。 .c_str()返回的指针与指向std::string对象的指针不同,C ++标准也不需要它,但返回的C字符串属于并由C ++对象管理。 / p>

答案 1 :(得分:3)

std::string没有转换为const char*,所以你必须致电.c_str() - 没有明确的演员会帮助你。

答案 2 :(得分:2)

  

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

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

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

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

  

我认为自动类型转换应该完成它的工作,即自动将C ++字符串转换为.c_str()。我错了吗?

是的,它可以做到,但不安全(见链接可能的问题)。

  

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

c_str()无法将std :: string对象转换为static_cast<> ...请记住,字符串对象本身包含所有其他内容,并且通常(除了最小的所有内容外) strings)只有一个指向实际文本数据的指针。