字符串的区别。h和装运箱吗?

时间:2021-02-24 03:14:15

What is the difference between string.h and cstring?

弦之间的区别是什么?h和装运箱吗?

Which one should be used for C and which one for C++ (if at all)?

哪一个应该用于C,哪一个应该用于c++(如果有的话)?

6 个解决方案

#1


20  

In C++ you should include cstring as the header while in c you should include string.h as the header.

在c++中,应该包括cstring作为header,而在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...

例如:字符串。因为h成为字符串的头。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 to memchr() specified in 21.7.

表55描述了标题 。内容与标准的C库头相同,在21.7中指定了对memchr()的更改。

While 21.7 Null-terminated sequence utilities states:

而21.7无终止序列效用说明:

The function signature memchr(const void*, int, size_t) shall be replaced by the two declarations:

函数签名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);

both of which shall have the same behavior as the original declaration.

两者具有与原始声明相同的行为。

Annex D (normative) Compatibility features [depr] states:

附件D(规范性)兼容性特征[depr]指出:

D.6 C standard library headers

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.

为了与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>

<断言。h> <浮动。h> <数学。h> < stddef。h > < tgmath。h > <复杂。h> < inttypes。h > < setjmp。h > < stdio。h > <。h > < ctype。h > < iso646。h > <信号。h> < stdint。h > < uchar。h > < errno。h > <限制。h> < stdarg。h > < stdlib。h > < wchar。h > < fenv。h > <语言环境。h> < stdbool。h > <字符串。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 corresponding cname 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).

每个C标头都有表单名的名称。h的行为就好像每个由相应的cname头放在标准库名称空间中的名称都放在全局名称空间范围内。不确定这些名称是在名称空间std的名称空间范围(3.3.6)中首先声明还是定义的,然后通过显式的使用声明将它们注入到全局名称空间范围(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 ]

3[示例:header 肯定地在名称空间std中提供了它的声明和定义。它也可以在全局名称空间中提供这些名称。标题< stdlib。h>无疑地在全局命名空间中提供了相同的声明和定义,就像在C标准中一样。它还可以在名称空间std. -end示例中提供这些名称。

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而不是string似乎没有明显的优势。如@Alf所言,使用cstring作为header时,由于使用了不合格的函数名,可能会出现一些编译问题。因此,给定帽子,使用字符串没有明显的缺点。h或使用cstring的优点,我认为如果使用得当,可以在c++中使用。

#2


4  

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下定义的。

#3


4  

There is a subtle difference between string.h and cstring

字符串之间有细微的差别。因为h和字符串

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.

字符串。h将标识符放在全局名称空间中,也可以将它们放在标准名称空间中。而cstring将标识符放在标准名称空间中,并可能将它们放在全局命名空间中。您肯定不希望使用cstring行为,因为使用strlen的代码可以在一个编译器上正常工作,然后在另一个编译器上无法编译。它非常令人不快的意外。所以对于C和c++,使用更安全的字符串。h。

#4


4  

You can use string.h for both C & C++.

您可以使用字符串。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和现实世界中,所有c++编译器都会提供字符串。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++中列出了所有18个header,在c++ 98 spec: assert中。h,iso646。h,setjmp。h,头。h,wchar。h,ctype。h,限制。h,信号。h,stdlib。h,wctype。h,errno。h,语言环境。h,stdarg。h,字符串。h,浮动。h,数学。h,stddef。h,time.h

#5


2  

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.

header的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函数的重载,以便如果输入参数是指向非const数据的指针,则允许函数返回指向非const数据的指针,而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++版本的header必须将它们的名称放在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作为typedefs,这一事实使它们无法为这些类型提供std::codecvt专门化。

#6


1  

Apparently cstring is for C++ and string.h is for C.

显然cstring代表c++和字符串。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.

值得一提的是,如果从字符串切换。h到cstring,记得在调用所有string函数之前添加std::。

#1


20  

In C++ you should include cstring as the header while in c you should include string.h as the header.

在c++中,应该包括cstring作为header,而在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...

例如:字符串。因为h成为字符串的头。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 to memchr() specified in 21.7.

表55描述了标题 。内容与标准的C库头相同,在21.7中指定了对memchr()的更改。

While 21.7 Null-terminated sequence utilities states:

而21.7无终止序列效用说明:

The function signature memchr(const void*, int, size_t) shall be replaced by the two declarations:

函数签名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);

both of which shall have the same behavior as the original declaration.

两者具有与原始声明相同的行为。

Annex D (normative) Compatibility features [depr] states:

附件D(规范性)兼容性特征[depr]指出:

D.6 C standard library headers

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.

为了与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>

<断言。h> <浮动。h> <数学。h> < stddef。h > < tgmath。h > <复杂。h> < inttypes。h > < setjmp。h > < stdio。h > <。h > < ctype。h > < iso646。h > <信号。h> < stdint。h > < uchar。h > < errno。h > <限制。h> < stdarg。h > < stdlib。h > < wchar。h > < fenv。h > <语言环境。h> < stdbool。h > <字符串。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 corresponding cname 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).

每个C标头都有表单名的名称。h的行为就好像每个由相应的cname头放在标准库名称空间中的名称都放在全局名称空间范围内。不确定这些名称是在名称空间std的名称空间范围(3.3.6)中首先声明还是定义的,然后通过显式的使用声明将它们注入到全局名称空间范围(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 ]

3[示例:header 肯定地在名称空间std中提供了它的声明和定义。它也可以在全局名称空间中提供这些名称。标题< stdlib。h>无疑地在全局命名空间中提供了相同的声明和定义,就像在C标准中一样。它还可以在名称空间std. -end示例中提供这些名称。

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而不是string似乎没有明显的优势。如@Alf所言,使用cstring作为header时,由于使用了不合格的函数名,可能会出现一些编译问题。因此,给定帽子,使用字符串没有明显的缺点。h或使用cstring的优点,我认为如果使用得当,可以在c++中使用。

#2


4  

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下定义的。

#3


4  

There is a subtle difference between string.h and cstring

字符串之间有细微的差别。因为h和字符串

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.

字符串。h将标识符放在全局名称空间中,也可以将它们放在标准名称空间中。而cstring将标识符放在标准名称空间中,并可能将它们放在全局命名空间中。您肯定不希望使用cstring行为,因为使用strlen的代码可以在一个编译器上正常工作,然后在另一个编译器上无法编译。它非常令人不快的意外。所以对于C和c++,使用更安全的字符串。h。

#4


4  

You can use string.h for both C & C++.

您可以使用字符串。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和现实世界中,所有c++编译器都会提供字符串。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++中列出了所有18个header,在c++ 98 spec: assert中。h,iso646。h,setjmp。h,头。h,wchar。h,ctype。h,限制。h,信号。h,stdlib。h,wctype。h,errno。h,语言环境。h,stdarg。h,字符串。h,浮动。h,数学。h,stddef。h,time.h

#5


2  

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.

header的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函数的重载,以便如果输入参数是指向非const数据的指针,则允许函数返回指向非const数据的指针,而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++版本的header必须将它们的名称放在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作为typedefs,这一事实使它们无法为这些类型提供std::codecvt专门化。

#6


1  

Apparently cstring is for C++ and string.h is for C.

显然cstring代表c++和字符串。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.

值得一提的是,如果从字符串切换。h到cstring,记得在调用所有string函数之前添加std::。