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

时间:2008-09-20 20:45:25

标签: c++ c stl string c-strings

现在有充分的理由在C ++中使用C字符串吗?我的教科书在某些方面的例子中使用它们,我觉得使用std :: string会更容易。

18 个答案:

答案 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设计师曾使用终止字符串。那是一个糟糕的决定;现在这是一个糟糕的决定。