现在有充分的理由在C ++中使用C字符串吗?我的教科书在某些方面的例子中使用它们,我觉得使用std :: string会更容易。
答案 0 :(得分:22)
我必须使用它们的唯一原因是与使用C样式字符串的第三方库连接时。出于性能原因,可能还会有一些深奥的情况,你会使用C样式字符串,但通常情况下,使用C ++字符串上的方法可能会更快,因为内联和专业化等等。
在使用这些API时,您可以在许多情况下使用c_str()
方法,但是您应该知道返回的char *是const,并且您不应该通过该指针修改字符串。在这种情况下,您仍然可以使用向量< char>相反,至少可以获得更容易的内存管理。
答案 1 :(得分:14)
更多内存控制说明:
C字符串是POD类型,因此可以在应用程序的只读数据段中分配它们。如果在命名空间范围内声明并定义std::string
常量,编译器将生成在main()
之前运行的其他代码,这些代码为每个常量调用std::string
构造函数。如果您的应用程序有许多常量字符串(例如,如果您生成了使用常量字符串的C ++代码),则在这种情况下可能更喜欢C字符串。
std::string
的某些实现支持称为SSO(“短字符串优化”或“小字符串优化”)的功能,其中std::string
类包含最长为特定长度的字符串的存储。这会增加std::string
的大小,但通常会显着降低免费存储分配/解除分配的频率,从而提高性能。如果std::string
的实现不支持SSO,那么在堆栈上构造空std::string
仍将执行免费存储分配。如果是这种情况,使用临时堆栈分配的C字符串可能对使用字符串的性能关键代码有帮助。当然,当你这样做时,你必须小心不要用脚射击自己。
答案 2 :(得分:8)
因为它们来自众多API /库?
答案 3 :(得分:3)
假设您的代码中有一些字符串常量,这是一个非常常见的需求。最好将它们定义为C字符串而不是C ++对象 - 更轻量级,可移植等等。现在,如果您要将这些字符串传递给各种函数,那么如果这些函数接受C字符串而不需要C ++字符串对象。
当然,如果字符串是可变的,那么使用C ++字符串对象会更方便。
答案 4 :(得分:3)
记忆控制。我最近不得不在大规模多线程应用程序中处理大小为200-300 MB的字符串(实际上来自数据库的blob)。这种情况下,只有一个字符串的副本可能会破坏32位地址空间。我必须知道确切存在多少个字符串副本。虽然我是STL布道者,但我使用了char *因为它给了我保证没有分配额外的内存甚至额外的副本。我确切地知道它需要多少空间。
除此之外,标准的STL字符串处理错过了一些很棒的C函数来进行字符串处理/解析。值得庆幸的是,std :: string具有用于const访问内部缓冲区的c_str()方法。要使用printf(),你仍然需要使用char *(这是一个疯狂的C ++团队的想法,不包括类似printf的功能,这是C中最有用的函数之一。我希望boost :: format将很快就会被列入STL。
答案 5 :(得分:2)
如果C ++代码是“深度”(接近内核,严重依赖于C库等),您可能希望显式使用C字符串以避免进出std :: string的大量转换。当然,如果你正在与其他语言域(Python,Ruby等)接口,你可能出于同样的原因这样做。否则,请使用std :: string。
答案 6 :(得分:2)
如果函数需要常量字符串,我仍然更喜欢使用'const char *'(或const wchar_t *),即使程序使用std :: string,CString,EString或其他任何地方。
在大型代码库中有太多的字符串来源,以确保调用者将字符串作为std :: string,并且'const char *'是最小的公分母。
答案 7 :(得分:2)
在几个平台上花费太多,太多,太多时间调试初始化规则和每个可想到的字符串实现之后,我们需要静态字符串为const char *。
在花费太多,远,太多时间调试错误的char *代码和内存泄漏后,我建议所有非静态字符串都是某种类型的字符串对象...直到分析显示你可以而且应该做得更好; - )
答案 8 :(得分:2)
教科书具有老式的C字符串,因为许多基本功能仍然希望它们作为参数,或者返回它们。此外,它还可以深入了解内存中字符串的底层结构。
答案 9 :(得分:2)
有些帖子提到内存问题。这可能是避开std :: string的一个很好的理由,但char *可能不是最好的替代品。它仍然是一种OO语言。你自己的字符串类可能比char *更好。它可能更有效 - 例如,您可以应用小字符串优化。
在我的情况下,我试图从2GB文件中获取大约1GB的字符串,将它们填入大约60个字段的记录中,然后将它们分类为不同字段的7倍。我的前辈代码用char *花了25个小时,我的代码在1小时内运行。
答案 10 :(得分:1)
对于诸如大多数嵌入式平台之类的应用程序,在这些应用程序中,您没有堆来存储被操纵的字符串,以及需要确定性预分配字符串缓冲区。
答案 11 :(得分:1)
不知道std :: string的旧代码。此外,在使用std :: ifstream或std :: ofstream的C ++ 11打开文件之前,只能使用const char *作为文件名的输入。
答案 12 :(得分:1)
1)“string constant”是一个C字符串(const char *),将其转换为const std :: string&是运行时过程,不一定简单或优化。 2)fstream库使用c风格的字符串来传递文件名。
我的经验法则是传递const std :: string&如果我要将数据用作std :: string(例如,当我将它们存储在向量中时),以及在其他情况下使用const char *。
答案 13 :(得分:1)
c字符串不会带来成为类的开销。
c字符串通常可以使代码更快,因为它们更接近机器级别
这并不是说,你不能用它们编写错误的代码。与其他所有结构一样,它们可能被滥用。
由于历史原因,有大量的图书馆电话需要它们。
学习使用c字符串和stl字符串,并在有意义的时候使用它们。
答案 14 :(得分:1)
这取决于您使用的库。例如,在使用MFC时,在使用Windows API的各个部分时,通常更容易使用CString。它似乎在Win32应用程序中的性能优于std :: string。
但是,std :: string是C ++标准的一部分,所以如果你想要更好的可移植性,请使用std :: string。
答案 15 :(得分:1)
根据选择,通常没有理由选择原始C字符串(char*
)而不是C ++字符串(std::string
)。但是,通常你没有选择的奢侈品。例如,由于历史原因,std::fstream
的构造函数采用C字符串。另外,C库(你猜对了!)使用C字符串。
在您自己的C ++代码中,最好使用std::string
并使用c_str()
function of std::string
根据需要提取对象的C字符串。
答案 16 :(得分:0)
STL字符串肯定更容易使用,我认为没有任何理由不使用它们。
如果需要与只接受C风格字符串作为参数的库进行交互,则可以始终调用字符串类的c_str()方法。
答案 17 :(得分:-2)
这样做的通常原因是您喜欢在字符串处理中编写缓冲区溢出。计数字符串优于终止字符串,很难理解为什么C设计师曾使用终止字符串。那是一个糟糕的决定;现在这是一个糟糕的决定。