<string>和<string.h>有什么区别?

66

这段代码为什么会出现问题

std::map <std::string , int> m;
m["a"]=1;

可以编译(我使用的是MSVC 2010)

#include <string>

但不能使用

#include <string.h>

?

11个回答

106
  • <string.h> 包含了一些旧的函数,例如用于 C 风格的以空字符结尾的字符串的 strcpystrlen
  • <string> 主要包含了 std::stringstd::wstring 和其他类。

41
需要注意的是,在C++中使用string.h已经被弃用。如果您需要其中包含的功能,则应该使用头文件cstring。这基本上完全绕过了“这两者之间有什么区别”的问题,因为很明显其中一个来自C库。 - Mike Bailey

23

string.h是C语言头文件,不是C++头文件,没有例外!


你的意思是当我有一对.h/.cpp文件时,我应该删除.h文件,还是你的回答只针对sdk文件? - Valmond
20
我认为更好的说法是:<string> 是 C++ 的头文件,而不是 C 的头文件。 - iammilind

16

<string.h>是C字符串库 - http://www.cplusplus.com/reference/clibrary/cstring/

<string>是C++字符串类 - http://www.cplusplus.com/reference/string/

根据Nicol Bolas评论和一些谷歌搜索,<cstring>通常会将与<string.h>相同的内容导入到std命名空间中。 <string.h>通常会将所有内容导入全局命名空间。 但是根据我的谷歌搜索结果,这似乎取决于您使用的库实现。

就我个人而言,只有在需要C风格字符串帮助程序时才使用<cstring>


2
<cstring>不是<string.h>的同义词。<cstring>将内容放置在std命名空间中(也可能将它们留在std命名空间之外),而<string.h>则不会这样做。 - Nicol Bolas
1
在C++中,使用C风格的.h头文件已经被弃用。 - Prasoon Saurav
要被弃用,它必须首先成为标准的一部分,而它从未成为过。@PrasoonSaurav - Peter Wood
1
@PeterWood:请查看C++03的附录D [D.5]。 - Prasoon Saurav

13

string.h是C语言的头文件,而string则是C++语言的头文件。


2
<string.h> 也可以被视为 C++ 的头文件。 :) - iammilind
不是!<cstring> 应该与 C++ 一起使用。 - Holger Jakobs
是的,C头文件与C++兼容,但它已被弃用,我们应该使用cstring。 - HackerDaGreat57

9

<string.h>包含C库字符串函数,例如strlenstrcmp等。

<string>包含std::basic_string的定义,其中有typedefs std::stringstd::wstring。这就是区别所在。

除了它们都处理字符串之外,它们实际上没有任何关系。


5

这两个是完全不同的头文件。

<string> 是C++中的 string 类。

<string.h> 或者 <cstring> 定义了操作C字符串和数组的函数。


3

如上所述,string.hcstring是C头文件(而cstring基本上是string.h的C++包装器),包含用于C字符串的函数,这些字符串是以'\0'结尾的char[]。您需要使用C++类字符串,其头文件为<string>


2

我认为<string.h>只适用于C语言,而<string>适用于C++语言。因此,包含string.h是行不通的。


1
  • 在Adrian的评论后进行了编辑
  1. C中,要使用旧的C风格字符串特性(包括strlen(char*)),我们写成这样:

     // C
     #include <string.h>
    

    这是C中唯一的方法。包含这个头文件将在全局范围内定义和声明一些实际的函数(如strlenstrcmp,...)。

  2. C++中,这种包含方式继续存在,因为C++编译器应该与大多数(99%)的C代码兼容。以下相同的代码包含了旧的C风格字符串特性(包括strlen(char*)):

     // C++
     #include <string.h>
    
  3. C++中,为了避免混淆,语言团队将旧的头文件重命名为遗留文件,我们建议写成这样,而不是2.:

     // C++
     #include <cstring.h>
    
  4. 或者,由于C++倾向于省略末尾的“.h”,我们可以写成这样:

     // C++
     #include <cstring>
    
摘要:1、2、3和4都是指示旧的C风格字符串特性(包括strlen(char*))的相同事物。
另一方面,C++引入了一个新的目标容器类,名为std::string。要包含这个新的C++风格的字符串类,我们需要写入以下代码:
```cpp // C++ #include ```
摘要:5. 是带来新的C++字符串类特性的唯一方法,该类名为std::string
情节转折: <string>本身导入了<cstring>(在大多数编译器中)。因此,对于使用旧的C风格字符串特性,我所提供的五个示例都可以正常工作,没有错误。要使用新的C++字符串类,同样,<string>是唯一的方法。

你似乎有点困惑。事实上,在大多数系统中,#include <string.h>实际上(或者可能是)等同于#include <cstring>。正如其他答案中指出的那样。 - undefined
@Adrian Mole - 哎呀,你说得对,我试图对每个情况都给出过于详细的解释(而不像其他人那样简洁地解释较少的情况),结果自己陷入了困境。我刚刚立即编辑了答案。谢谢你!事后想法:事实证明,我的代码包括了<string.h>,因为我的编译器中的另一个头文件<iostream>仍然包括了<string>,而<string>又包括了<cstring>。 - undefined
请注意,<string>通常包括string.h,但据我所知,并不要求标准这样做。但我可能错了。 - undefined
你又说对了,兼容性或其他头文件的包含并没有绝对的规则(当有一些事情发生时,可能是编译环境的感激之情),所以有时候我只使用<iostream>和一个string类时也会遇到错误,在这台电脑上这个编译器会报错,而在那台电脑上那个编译器却没有错误。(不是C++的不同版本,而是不同的编译器) - undefined

0

<string.h> 是 C 标准库头文件,而 <string> 则是 C++ 的。实际上,所有的 C 标准头文件都有 .h 扩展名,而没有一个 C++ 头文件有 .h 扩展名。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接