为什么在c ++中使用c字符串?

现在有没有什么好的理由在C ++中使用C-strings? 我的教科书在某些方面的例子中使用它们,我觉得使用std :: string会更容易。

我必须使用它们的唯一原因是与使用C样式字符串的第三方库连接时。 出于性能原因,可能还会有一些深奥的情况,你会使用C样式字符串,但更多时候,由于内联和专业化等原因,使用C ++字符串上的方法可能更快。

在使用这些API时,您可以在许多情况下使用c_str()方法,但是您应该知道返回的char *是const,并且您不应该通过该指针修改字符串。 在这种情况下,您仍然可以使用vector ,至少可以获得更简单的内存管理。

更多内存控制说明:

C字符串是POD类型,因此可以在应用程序的只读数据段中分配它们。 如果在命名空间范围内声明和定义std::string常量,编译器将生成在main()之前运行的其他代码,该代码为每个常量调用std::string构造函数。 如果您的应用程序有许多常量字符串(例如,如果您生成了使用常量字符串的C ++代码),则在这种情况下可能更喜欢C字符串。

std::string一些实现支持一个名为SSO的function(“短字符串优化”或“小字符串优化”),其中std::string类包含最长为特定长度的字符串的存储。 这会增加std::string的大小,但通常会显着降低免费存储分配/解除分配的频率,从而提高性能。 如果std::string实现不支持SSO,那么在堆栈上构造一个空的std::string仍将执行自由存储分配。 如果是这种情况,使用临时堆栈分配的C字符串可能对使用字符串的性能关键代码有帮助。 当然,当你这样做时,你必须小心不要射击自己。

因为他们是如何来自众多API /库的?

假设你的代码中有一些字符串常量,这是一个非常常见的需求。 最好将它们定义为C字符串而不是C ++对象 – 更轻量级,可移植等等。现在,如果您要将这些字符串传递给各种函数,那么如果这些函数接受C字符串而不需要C ++字符串对象。

当然,如果字符串是可变的,那么使用C ++字符串对象会更方便。

记忆控制。 我最近不得不在大规模multithreading应用程序中处理大小为200-300 MB的字符串(实际上是来自数据库的blob)。 这种情况下,只有一个字符串的副本可能会破坏32位地址空间。 我必须知道确切存在多少个字符串副本。 虽然我是STL布道者,但我使用了char *因为它给了我保证没有分配额外的内存甚至额外的副本。 我确切地知道它需要多少空间。

除此之外,标准的STL字符串处理错过了一些很棒的C函数来进行字符串处理/解析。 值得庆幸的是,std :: string具有用于const访问内部缓冲区的c_str()方法。 要使用printf(),你仍然需要使用char *(对于C ++团队来说,这是一个疯狂的想法,不包括类似printf的function,这是C中最有用的function之一。我希望boost :: format会很快就会被列入STL。

如果函数需要一个常量字符串,我仍然喜欢使用’const char *’(或const wchar_t *),即使程序使用std :: string,CString,EString或其他任何地方。

在大型代码库中有太多的字符串源,以确保调用者将字符串作为std :: string,并且’const char *’是最小的公分母。

教科书具有老式的C字符串,因为许多基本function仍然期望它们作为参数,或者返回它们。 此外,它还可以深入了解内存中字符串的底层结构。

如果C ++代码是“深度”(接近内核,严重依赖于C库等),您可能希望显式使用C字符串以避免进出std :: string的大量转换。 当然,如果您正在与其他语言域(Python,Ruby等)连接,您可能会出于同样的原因这样做。 否则,请使用std :: string。

一些post提到内存问题。 这可能是避开std :: string的一个很好的理由,但char *可能不是最好的替代品。 它仍然是一种OO语言。 你自己的字符串类可能比char *更好。 它甚至可能更有效 – 例如,您可以应用小字符串优化。

在我的情况下,我试图从2GB文件中获取大约1GB的字符串,将它们填入大约60个字段的记录中,然后将它们分类为不同字段的7倍。 我的前辈代码用char *花了25个小时,我的代码在1小时内运行。

在远程,远,太多时间调试初始化规则和在几个平台上的每个可想到的字符串实现之后,我们需要静态字符串为const char *。

花了很多,远,太多时间调试错误的char *代码和内存泄漏我建议所有非静态字符串都是某种类型的字符串对象…直到分析显示你可以而且应该做更好的事情;-)

给定选择,通常没有理由选择原始C字符串( char* )而不是C ++字符串( std::string )。 但是,通常你没有选择的奢侈品。 例如,由于历史原因, std::fstream的构造函数采用C字符串。 此外,C库(你猜对了!)使用C字符串。

在您自己的C ++代码中,最好使用std::string并使用std::stringc_str()函数根据需要提取对象的C std::string

这取决于您正在使用的库。 例如,在使用MFC时 ,在使用Windows API的各个部分时,通常更容易使用CString。 它似乎也比Win32应用程序中的std :: string表现更好。

但是,std :: string是C ++标准的一部分,因此如果您想要更好的可移植性,请使用std :: string。

对于诸如大多数嵌入式平台之类的应用程序,在这些应用程序中,您没有堆来存储被操作的字符串,以及需要确定性预分配字符串缓冲区。

c字符串不承担成为类的开销。

c字符串通常可以导致更快的代码,因为它们更接近机器级别

这并不是说,你不能用它们编写错误的代码。 它们可能像其他所有构造一样被滥用。

由于历史原因,有大量的图书馆电话需要它们。

学习使用c字符串和stl字符串,并在有意义的时候使用它们。

1)“字符串常量”是一个C字符串(const char *),将其转换为const std :: string并且是运行时进程,不一定简单或优化。 2)fstream库使用c样式字符串来传递文件名。

我的经验法则是传递const std :: string&如果我要将数据用作std :: string(例如,当我将它们存储在向量中时),而在其他情况下使用const char *。

不知道std :: string的遗留代码。 此外,在使用std :: ifstream或std :: ofstream的C ++ 11打开文件之前,只能使用const char *作为文件名的输入。

STL字符串肯定更容易使用,我认为没有任何理由不使用它们。

如果需要与只接受C风格字符串作为参数的库进行交互,则始终可以调用字符串类的c_str()方法。

这样做的通常原因是您喜欢在字符串处理中编写缓冲区溢出。 计数字符串优于终止字符串,很难理解为什么C设计师曾使用终止字符串。 那是一个糟糕的决定; 现在这是一个糟糕的决定。