string.h和cstring之间的区别?

时间:2011-12-05 03:51:54

标签: c++ c

string.hcstring之间有什么区别?

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

7 个答案:

答案 0 :(得分:20)

在C ++中,您应该包含cstring作为标题,而在c中,您应该包含string.h作为标题。

在C ++中

#include <cstring>

在C

#include <string.h>

C标准库中还提供了C标准库的功能,作为一般命名约定,它们由c预先设置为C标准库中的相应名称。

例如:
string.h成为cstring
stdio.h变为cstdio,依此类推......


由于其他答案为本次讨论增加了不同的篇幅,我觉得有必要参考神圣的标准来清除这一点。

根据 C ++ 11 20.9.14.6&amp; 7

  

表55描述了标题<cstring>   内容与标准C库头相同,更改为21.7中指定的memchr()

21.7空终止序列实用程序表示:

  

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

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

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

D.6 C标准库标题

  

1为了与C标准库和C Unicode TR兼容,C ++标准库提供了25个C标头,如表151所示。

其中包括:

  

<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>

继续,

  

2 每个C标头(每个标头都有name.h形式的名称,就好像每个名称放置在标准库名称空间中的相应cname header放置在全局范围内命名空间范围。未指定这些名称是在名称空间std的名称空间作用域(3.3.6)中首先声明或定义的,然后通过显式使用声明(7.3.3)注入全局名称空间作用域。

     

3 [示例:标题<cstdlib>确定在命名空间std中提供其声明和定义。它还可以在全局命名空间中提供这些名称。标头<stdlib.h>确实在全局命名空间中提供相同的声明和定义,就像在C标准中一样。它还可以在命名空间std中提供这些名称。 - 例子]

结论:

从以上参考文献:
我在先前的建议中得到了纠正,使用cstring而不是string.h似乎没有明显的优势,而@Alf建议在使用{{{{}}时可能存在一些编译问题,因为使用了不合格的函数名称1}}作为标题。因此,使用cstring或使用string.h的优势没有明显的优势,我认为如果以适当的方式使用,可以在C ++中使用。

答案 1 :(得分:4)

在C ++中,C语言头在命名空间std下定义。因此,如果您在C ++中使用这些标头,请使用cstring并消除.h。

答案 2 :(得分:4)

你可以使用string.h进行C&amp; C ++。

在C ++ 98规范中,它定义了cstring(在主要规范中)和string.h(在附件D.5中,标准C库头,为了兼容性),它定义了一些与string.h相同的字符串函数。 C.在现实世界中,所有C ++编译器都将提供string.h以与C代码兼容。

所以,在我看来,由于C ++代码可能由C编码器维护,而习惯来自C,我更喜欢string.h。它足够清晰,广为人知,兼容性更强(使用C)。

BTW,我在C ++中列出了所有18个头文件,以便与C语言兼容,在C ++ 98规范中: 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

答案 3 :(得分:4)

string.h cstring

之间存在细微差别

Alf P. Steinbach的答案(可以作为对问题的评论):

string.h将标识符放在全局命名空间中,也可以将它们放在标准命名空间中。虽然cstring将标识符放在标准名称空间中,但也可以将它们放在全局名称空间中。您绝对不希望cstring行为,因为代码例如只使用strlen可以在一个编译器上正常工作,然后无法用另一个编译器编译。这是非常令人不快的惊喜。因此,对于 C和C ++ ,请使用更安全的string.h

答案 4 :(得分:2)

标头的C ++版本实际上与C版本有一些差异。在C中,某些类型是作为typedef实现的,但是对于C ++来说,它可以防止模板特化等事情对这些类型*进行处理,因此C ++会将一些C typedef转换为实际类型。这意味着包含这些typedef的C ++的C ++版本必须省略它们。

C ++还允许重载,因此<cstring>的C ++版本指定C函数的一些重载,以允许函数返回指向非const数据的指针,如果输入参数是指向非const数据的指针,而C函数只接受指向const的指针。

我想,但是现在无法找到标准中的位来验证这一点,标头的C ++版本必须将它们的名称放在std命名空间中,并且只将它们放在全局命名空间中作为可选的扩展名。

*  例如,以下代码:

typedef int Foo;
template<typename T> struct Bar {};
template<> struct Bar<int> {};
template<> struct Bar<Foo> {};

导致以下错误:

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.

在C中,wchar_t是一个typedef,因此这将阻止一个特殊化应用于wchar_t,但不会阻止用于wchar_t的任何底层类型。 MSVC 2010将char32_t和char16_t实现为typedef这一事实阻止了它们为这些类型提供std :: codecvt特化。

答案 5 :(得分:1)

显然cstring适用于C ++,string.h适用于C。

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

答案 6 :(得分:0)

使用<cstring>时,一些答案建议使用std::命名空间。但是,代码仍将在没有std名称空间的情况下进行编译和运行。这是因为: <cstring> = "string.h" + <functions defined in the std namespace>

这样做是为了保持与C的兼容性。 自己添加<cstring>并同时调用memcpy()std::memcpy()进行尝试。