C++ string.h 和 cstring 的区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8380805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between string.h and cstring?
提问by Beginner
What is the difference between string.h
and cstring
?
string.h
和 和有cstring
什么区别?
Which one should be used for C and which one for C++ (if at all)?
哪一个应该用于 C,哪一个用于 C++(如果有的话)?
回答by Alok Save
In C++ you should include cstring
as the header while in c you should include string.h
as the header.
在 C++ 中,您应该cstring
作为标题包含,而在 c 中,您应该string.h
作为标题包含。
In C++
在 C++ 中
#include <cstring>
In C
在 C
#include <string.h>
Features of C standard Library are also provided in the C++ Standard library and as a general naming convention they are pre-pended by an c
to the corresponding names in C standard library.
C++ 标准库中也提供了 C 标准库的特性,作为通用命名约定,它们c
在 C 标准库中的相应名称前面加上 。
For Example:string.h
becomes cstring
stdio.h
becomes cstdio
and so on...
例如:string.h
变成cstring
stdio.h
变成cstdio
等等......
Since other answers have added different dimensions to this discussion,I felt compelled to refer the holy standard to clear this bit.
由于其他答案为这个讨论增加了不同的维度,我觉得不得不参考神圣标准来清除这一点。
As per C++11 20.9.14.6 & 7:
根据C++11 20.9.14.6 & 7:
Table 55 describes the header
<cstring>
.
The contents are the same as the Standard C library header , with the change tomemchr()
specified in 21.7.
表 55 描述了标题
<cstring>
。
内容与标准 C 库头文件相同,更改为memchr()
21.7 中指定。
While 21.7 Null-terminated sequence utilitiesstates:
虽然21.7 空终止序列实用程序指出:
The function signature
memchr(const void*, int, size_t)
shall be replaced by the two declarations:const void* memchr(const void* s, int c, size_t n); void* memchr( void* s, int c, size_t n);
both of which shall have the same behavior as the original declaration.
函数签名
memchr(const void*, int, size_t)
应替换为两个声明:const void* memchr(const void* s, int c, size_t n); void* memchr( void* s, int c, size_t n);
两者都应与原始声明具有相同的行为。
Annex D (normative) Compatibility features [depr]states:
附件 D(规范性)兼容性特性 [depr]规定:
D.6 C standard library headers
D.6 C 标准库头文件
1 For compatibility with the C standard library and the C Unicode TR, the C++ standard library provides the 25 C headers, as shown in Table 151.
1 为了与 C 标准库和 C Unicode TR 兼容,C++ 标准库提供了 25 个 C 头文件,如表 151 所示。
Which include:
其中包括:
<assert.h> <float.h> <math.h> <stddef.h> <tgmath.h>
<complex.h> <inttypes.h> <setjmp.h> <stdio.h> <time.h>
<ctype.h> <iso646.h> <signal.h> <stdint.h> <uchar.h>
<errno.h> <limits.h> <stdarg.h> <stdlib.h> <wchar.h>
<fenv.h> <locale.h> <stdbool.h> <string.h> <wctype.h>
<assert.h> <float.h> <math.h> <stddef.h> <tgmath.h>
<complex.h> <inttypes.h> <setjmp.h> <stdio.h> <time.h>
<ctype.h> <iso646.h> <signal.h> <stdint.h> <uchar.h>
<errno.h> <limits.h> <stdarg.h> <stdlib.h> <wchar.h>
<fenv.h> <locale.h> <stdbool.h> <string.h> <wctype.h>
Further on,
进一步,
2 Every C header, each of which has a name of the form
name.h
, behaves as if each name placed in the standard library namespace by the correspondingcname header
is placed within the global namespace scope.It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).3 [ Example: The header
<cstdlib>
assuredly provides its declarations and definitions within the namespace std. It may also provide these names within the global namespace. The header<stdlib.h>
assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard. It may also provide these names within the namespace std. —end example ]
2 每个 C 头文件,每个头文件都有一个形式为 的名称,其
name.h
行为就好像由相应的标准库名称空间中的每个名称放置在cname header
全局名称空间范围内。未指定这些名称是否首先在命名空间 std 的命名空间范围 (3.3.6) 内声明或定义,然后通过显式 using 声明 (7.3.3) 注入全局命名空间范围。3 [ 示例:标题
<cstdlib>
肯定会在命名空间 std 中提供其声明和定义。它还可以在全局命名空间内提供这些名称。头文件<stdlib.h>
确实在全局命名空间中提供了相同的声明和定义,就像在 C 标准中一样。它还可以在命名空间 std 中提供这些名称。—结束示例]
Conclusion:
结论:
From the above references:
I stand corrected on my earlier suggestion, there seems to be no apparent advantage of using cstring
over string.h
while as @Alf suggested there might be some compilation issues due to use of unqualified function names when using cstring
as header. So given hat there is no apparent dis-advantage of using string.h
or advantage of using cstring
, I think either can be used in C++ if used in a proper manner.
从上面的参考资料:
我对我之前的建议进行了纠正,使用cstring
over string.h
while似乎没有明显的优势,正如@Alf 建议的那样,由于在cstring
用作标头时使用了不合格的函数名称,可能会出现一些编译问题。所以鉴于 hat 没有明显的使用string.h
或使用优势cstring
,我认为如果以适当的方式使用,它们都可以在 C++ 中使用。
回答by Jagannath
In C++, C language headers are defined under the namespace std. So, if you are using those headers in C++, use cstring and eliminate .h .
在 C++ 中,C 语言头文件定义在命名空间 std 下。因此,如果您在 C++ 中使用这些头文件,请使用 cstring 并消除 .h 。
回答by Googol
You can use string.h for both C & C++.
您可以将 string.h 用于 C 和 C++。
In C++ 98 spec, it define both the cstring (in main spec) and string.h (in Annex D.5, Standard C library headers, for compatibility), which define some string function the same as string.h in C. And in real world, all C++ compiler will provide string.h for compatibility to C code.
在 C++ 98 规范中,它同时定义了 cstring(在主规范中)和 string.h(在附件 D.5,标准 C 库头文件中,为了兼容性),它们定义了一些与 C 中的 string.h 相同的字符串函数。在现实世界中,所有 C++ 编译器都会提供 string.h 以兼容 C 代码。
So, in my opinion, as C++ code maybe maintain by C coder, and the habit from C, I prefer string.h. It's clear enough, wide known, and more compatibility (with C).
所以,在我看来,由于 C++ 代码可能由 C 编码人员维护,以及 C 的习惯,我更喜欢 string.h。它足够清晰,广为人知,并且具有更高的兼容性(与 C)。
BTW, I list the all 18 headers in C++ for compatibility with C, in C++ 98 spec: assert.h, iso646.h, setjmp.h, stdio.h, wchar.h, ctype.h, limits.h, signal.h, stdlib.h, wctype.h, errno.h, locale.h, stdarg.h, string.h, float.h, math.h, stddef.h, time.h
顺便说一句,为了与 C 兼容,我在 C++ 98 规范中列出了 C++ 中的所有 18 个头文件:assert.h、iso646.h、setjmp.h、stdio.h、wchar.h、ctype.h、limits.h、signal。 h、stdlib.h、wctype.h、errno.h、locale.h、stdarg.h、string.h、float.h、math.h、stddef.h、time.h
回答by Beginner
There is a subtle difference between string.hand cstring
string.h和cstring之间有细微的区别
Answer of Alf P. Steinbach(can be found as a comment to the asked question):
Alf P. Steinbach 的回答(可以作为对所问问题的评论找到):
string.h
places the identifiers in the global namespace, and may also place them in the standard namespace. While cstring
places the identifiers in the standard namespace, and may also place them in the global namespace. You definitely don't want that cstring
behavior, because code that e.g. uses just strlen
may work fine with one compiler, then fail to compile with another compiler. It's very unpleasant surprise. So for C and C++, use the more safe string.h
.
string.h
将标识符放在全局命名空间中,也可以将它们放在标准命名空间中。虽然cstring
将标识符放在标准命名空间中,也可以将它们放在全局命名空间中。您绝对不希望出现这种cstring
行为,因为例如使用的代码strlen
可能在一个编译器上运行良好,然后在另一个编译器上编译失败。这是非常不愉快的惊喜。所以对于C 和 C++,使用更安全的string.h
.
回答by Deqing
Apparently cstring
is for C++ and string.h
is for C.
显然cstring
是针对 C++ 的,string.h
也是针对 C 的。
One thing worth mentioning is, if you are switching from string.h
to cstring
, remember to add std::
before all your string function calls.
值得一提的是,如果您要从string.h
to切换cstring
,请记住std::
在所有字符串函数调用之前添加。
回答by bames53
The C++ version of the header actually has some differences from the C version. In C some types are implemented as typedefs, but for C++ that prevents things like template specialization from working on those types*, so C++ makes some C typedefs into real types. This means that the C++ version of C headers that contain those typedefs must omit them.
头文件的 C++ 版本实际上与 C 版本有一些不同。在 C 中,某些类型被实现为 typedef,但对于 C++ 来说,它会阻止模板特化之类的事情处理这些类型*,因此 C++ 将一些 C 类型定义变成了真正的类型。这意味着包含这些 typedef 的 C 头文件的 C++ 版本必须省略它们。
C++ also allows overloading and so the C++ version of <cstring>
specifies some overloads to C functions to allow a function to return a pointer to non-const data if the input argument is a pointer to non-const data, whereas the C function takes and returns only pointers to const.
C++ 还允许重载,因此 C++ 版本的 C++ 版本<cstring>
指定了一些 C 函数的重载,如果输入参数是指向非常量数据的指针,则允许函数返回指向非常量数据的指针,而 C 函数仅接受并返回指向 const 的指针。
Also I think, but can't find the bit in the standard to verify this right now, that the C++ versions of headers have to put their names in the std namespace and only put them in the global namespace as an optional extension.
我也认为,但现在找不到标准中的位来验证这一点,C++ 版本的标头必须将它们的名称放在 std 命名空间中,并且只将它们作为可选扩展放在全局命名空间中。
* For example the following code:
* 例如下面的代码:
typedef int Foo;
template<typename T> struct Bar {};
template<> struct Bar<int> {};
template<> struct Bar<Foo> {};
results in the following error:
导致以下错误:
main.cpp:7:19: error: redefinition of 'Bar<int>'
template<> struct Bar<Foo> {};
^~~~~~~~
main.cpp:5:19: note: previous definition is here
template<> struct Bar<int> {};
^
1 error generated.
In C wchar_t is a typedef, so this would prevent one from having a specialization that applies to wchar_t but not to whatever underlying type is used for wchar_t. The fact that MSVC 2010 implements char32_t and char16_t as typedefs prevents them from being able to offer the std::codecvt specializations for those types.
在 C 中 wchar_t 是一个 typedef,所以这会阻止一个专门化适用于 wchar_t 但不适用于 wchar_t 使用的任何基础类型。MSVC 2010 将 char32_t 和 char16_t 实现为 typedef 的事实使它们无法为这些类型提供 std::codecvt 特化。
回答by CyclicUniverse
While using <cstring>
, some answers suggest using std::
namespace. However, the code will still compile and run without the std
namespace. This is because:
<cstring> = "string.h" + <functions defined in the std namespace>
在使用时<cstring>
,一些答案建议使用std::
命名空间。但是,代码仍将在没有std
命名空间的情况下编译和运行。这是因为:
<cstring> = "string.h" + <functions defined in the std namespace>
This was done to maintain compatibility with C.
Try it yourself by including <cstring>
and calling both memcpy()
and std::memcpy()
.
这样做是为了保持与C兼容性通过包括自己尝试一下<cstring>
,并呼吁双方memcpy()
和std::memcpy()
。