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

发布于 2024-07-06 11:45:17 字数 80 浏览 7 评论 0原文

如今在 C++ 中使用 C 字符串有什么好的理由吗? 我的教科书在某些时候在示例中使用了它们,我真的觉得使用 std::string 会更容易。

Is there any good reason to use C strings in C++ nowadays? My textbook uses them in examples at some points, and I really feel like it would be easier just to use a std::string.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(18

我恋#小黄人 2024-07-13 11:45:18

我必须使用它们的唯一原因是与使用 C 样式字符串的第三方库交互时。 也可能存在一些深奥的情况,出于性能原因,您会使用 C 样式字符串,但通常情况下,由于内联和专门化等原因,在 C++ 字符串上使用方法可能会更快。

您可以使用 c_str() 方法在许多情况下使用此类 API 时,但您应该注意返回的 char * 是 const,并且您不应该通过该指针修改字符串。 在这种情况下,您仍然可以使用向量相反,至少可以获得更轻松的内存管理的好处。

The only reasons I've had to use them is when interfacing with 3rd party libraries that use C style strings. There might also be esoteric situations where you would use C style strings for performance reasons, but more often than not, using methods on C++ strings is probably faster due to inlining and specialization, etc.

You can use the c_str() method in many cases when working with those sort of APIs, but you should be aware that the char * returned is const, and you should not modify the string via that pointer. In those sort of situations, you can still use a vector<char> instead, and at least get the benefit of easier memory management.

卖梦商人 2024-07-13 11:45:18

更多内存控制注意事项:

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

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

A couple more memory control notes:

C strings are POD types, so they can be allocated in your application's read-only data segment. If you declare and define std::string constants at namespace scope, the compiler will generate additional code that runs before main() that calls the std::string constructor for each constant. If your application has many constant strings (e.g. if you have generated C++ code that uses constant strings), C strings may be preferable in this situation.

Some implementations of std::string support a feature called SSO ("short string optimization" or "small string optimization") where the std::string class contains storage for strings up to a certain length. This increases the size of std::string but often significantly reduces the frequency of free-store allocations/deallocations, improving performance. If your implementation of std::string does not support SSO, then constructing an empty std::string on the stack will still perform a free-store allocation. If that is the case, using temporary stack-allocated C strings may be helpful for performance-critical code that uses strings. Of course, you have to be careful not to shoot yourself in the foot when you do this.

过气美图社 2024-07-13 11:45:18

因为这就是它们来自众多 API/库的方式?

Because that's how they come from numerous API/libraries?

咆哮 2024-07-13 11:45:18

内存控制。 最近,我必须在大型多线程应用程序中处理大小约为 200-300 MB 的字符串(实际上是数据库中的 blob)。 在这种情况下,只要再复制一个字符串就可能会占用 32 位地址空间。 我必须确切地知道该字符串存在多少个副本。 虽然我是一个 STL 传播者,但我当时使用了 char * 因为它给了我保证没有分配额外的内存,甚至没有分配额外的副本。 我确切地知道它需要多少空间。

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

Memory control. I recently had to handle strings (actually blobs from a database) about 200-300 MB in size, in a massively multithreaded application. It was a situation where just-one-more copy of the string might have burst the 32-bit address space. I had to know exactly how many copies of the string existed. Although I'm an STL evangelist, I used char * then because it gave me the guarantee that no extra memory or even extra copy was allocated. I knew exactly how much space it would need.

Apart from that, standard STL string processing misses out on some great C functions for string processing/parsing. Thankfully, std::string has the c_str() method for const access to the internal buffer. To use printf() you still have to use char * though (what a crazy idea of the C++ team to not include (s)printf-like functionality, one of the most useful functions ever in C. I hope boost::format will soon be included in the STL.

猫九 2024-07-13 11:45:18

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

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

Let's say you have some string constants in your code, which is a pretty common need. It's better to define these as C strings than as C++ objects -- more lightweight, portable, etc. Now, if you're going to be passing these strings to various functions, it's nice if these functions accept a C string instead of requiring a C++ string object.

Of course, if the strings are mutable, then it's much more convenient to use C++ string objects.

忆梦 2024-07-13 11:45:18

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

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

If a function needs a constant string I still prefer to use 'const char*' (or const wchar_t*) even if the program uses std::string, CString, EString or whatever elsewhere.

There are just too many sources of strings in a large code base to be sure the caller will have the string as a std::string and 'const char*' is the lowest common denominator.

动次打次papapa 2024-07-13 11:45:18

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

Textbooks feature old-school C strings because many basic functions still expect them as arguments, or return them. Additionally, it gives some insight into the underlying structure of the string in memory.

思慕 2024-07-13 11:45:18

如果可以选择,通常没有理由选择原始 C 字符串 (char*) 而不是 C++ 字符串 (std::string)。 然而,通常您没有足够的选择余地。 例如,由于历史原因,std::fstream 的构造函数采用 C 字符串。 另外,C 库(您猜对了!)使用 C 字符串。

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

Given the choice, there is generally no reason to choose primitive C strings (char*) over C++ strings (std::string). However, often you don't have the luxury of choice. For instance, std::fstream's constructors take C strings, for historical reasons. Also, C libraries (you guessed it!) use C strings.

In your own C++ code it is best to use std::string and extract the object's C string as needed by using the c_str() function of std::string.

纵山崖 2024-07-13 11:45:18

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

If the C++ code is "deep" (close to the kernel, heavily dependent on C libraries, etc.) you may want to use C strings explicitly to avoid lots of conversions in to and out of std::string. Of, if you're interfacing with other language domains (Python, Ruby, etc.) you might do so for the same reason. Otherwise, use std::string.

攒一口袋星星 2024-07-13 11:45:18

在花费了太多太多的时间调试初始化规则和多个平台上每个可以想象的字符串实现之后,我们要求静态字符串为 const char*。

在花费了太多太多的时间调试错误的 char* 代码和内存泄漏之后,我建议所有非静态字符串都是某种类型的字符串对象......直到分析表明您可以而且应该做得更好;-)

After spending far, far, too much time debugging initialization rules and every conceivable string implementation on several platforms we require static strings to be const char*.

After spending far, far, too much time debugging bad char* code and memory leaks I suggest that all non-static strings be some type of string object ... until profiling shows that you can and should do something better ;-)

贱人配狗天长地久 2024-07-13 11:45:18

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

Legacy code that doesn't know of std::string. Also, before C++11 opening files with std::ifstream or std::ofstream was only possible with const char* as an input to the file name.

鸠魁 2024-07-13 11:45:18

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

就我而言,我试图从 2 GB 文件中获取大约 1 GB 的字符串,将它们填充到具有大约 60 个字段的记录中,然后对不同字段进行七次排序。 我前任的代码使用 char* 花了 25 个小时,而我的代码只用了 1 个小时就运行了。

Some posts mention memory concerns. That might be a good reason to shun std::string, but char* probably is not the best replacement. It's still an OO language. Your own string class is probably better than a char*. It may even be more efficient—you can apply the short string optimization, for instance.

In my case, I was trying to get about 1 GB worth of strings out of a 2 GB file, stuff them in records with about 60 fields and then sort them seven times of different fields. My predecessor's code took 25 hours with char*, and my code ran in one hour.

忆沫 2024-07-13 11:45:18
  1. “字符串常量”是一个 C 字符串 (const char *)。 将其转换为 const std::string& 是运行时过程,不一定简单或优化。
  2. fstream 库使用 C 样式字符串来传递文件名。

我的经验法则是,如果我无论如何都要将数据用作 std::string ,则传递 const std::string& (例如,当我将它们存储在矢量),以及其他情况下的 const char *

  1. "string constant" is a C string (const char *). Converting it to const std::string& is run-time process, not necessarily simple or optimized.
  2. The fstream library uses C-style strings to pass file names.

My rule of thumb is to pass const std::string& if I am about to use the data as std::string anyway (say, when I store them in a vector), and const char * in other cases.

心头的小情儿 2024-07-13 11:45:18

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

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

It depends on the libraries you're using. For example, when working with the MFC, it's often easier to use CString when working with various parts of the Windows API. It also seems to perform better than std::string in Win32 applications.

However, std::string is part of the C++ standard, so if you want better portability, go with std::string.

浪推晚风 2024-07-13 11:45:18

对于诸如大多数嵌入式平台之类的应用程序,您没有足够的堆来存储正在操作的字符串,并且需要对字符串缓冲区进行确定性预分配。

For applications such as most embedded platforms where you do not have the luxury of a heap to store the strings being manipulated, and where deterministic preallocation of string buffers is required.

小傻瓜 2024-07-13 11:45:18

C 字符串不承担作为类的开销。

C 字符串通常可以生成更快的代码,因为它们更接近机器级别。

这并不是说,你不能用它们写出糟糕的代码。 就像其他所有结构一样,它们也可能被滥用。

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

学习使用 C 字符串和 STL 字符串,并在有意义时使用它们。

C strings don't carry the overhead of being a class.

C strings generally can result in faster code, as they are closer to the machine level.

This is not to say, you can't write bad code with them. They can be misused, like every other construct.

There is a wealth of library calls that demand them for historical reasons.

Learn to use C strings, and STL strings, and use each when it makes sense to do so.

救星 2024-07-13 11:45:18

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

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

STL strings are certainly far easier to use, and I don't see any reason to not use them.

If you need to interact with a library that only takes C-style strings as arguments, you can always call the c_str() method of the string class.

追风人 2024-07-13 11:45:18

这样做的通常原因是您喜欢在字符串处理中编写缓冲区溢出。 计数字符串比终止字符串优越得多,很难理解为什么 C 设计者曾经使用终止字符串。 当时这是一个错误的决定; 现在这是一个错误的决定。

The usual reason to do it is that you enjoy writing buffer overflows in your string handling. Counted strings are so superior to terminated strings it's hard to see why the C designers ever used terminated strings. It was a bad decision then; it's a bad decision now.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文