28

What is the difference between string.h and cstring?

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

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Roman Byshko
  • 8,591
  • 7
  • 35
  • 57
  • 2
    C and C++ are not the same language. Since you mention `cstring` I'm assuming you mean C++ and have removed the `C` tag. – Brian Roach Dec 05 '11 at 03:54
  • 1
    @BrianRoach mm.. not quite, I wanted to have a comparison, what header should be used for which language. – Roman Byshko Dec 05 '11 at 03:55
  • 2
    that makes no sense since `cstring` *can't* be used in C. – Brian Roach Dec 05 '11 at 03:57
  • Right. I wanted to have this as an answer. There is not such a question on SO. So I thought if would be usefult to ask. – Roman Byshko Dec 05 '11 at 03:57
  • 7
    Oh wow ... googling `cstring` really improved my evening ... – Brian Roach Dec 05 '11 at 03:59
  • Joking aside ... you wanted an answer as to which to use, when using one of them was not possible? Are you seeing the fallacy in this logic? – Brian Roach Dec 05 '11 at 04:00
  • @BrianRoach I do not understand what the problem is. Can anybody ask questions or not? You are free to answer/downvote or do whatever you want to do. – Roman Byshko Dec 05 '11 at 04:01
  • @BrianRoach I pretended I do not know anything about them :) It's just another beginner question. – Roman Byshko Dec 05 '11 at 04:04
  • 4
    ¤ I think all answers you get here will be technically incorrect. I don't care to downvote them though. Anyway, [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]. Cheers & hth., – Cheers and hth. - Alf Dec 05 '11 at 04:04
  • @AlfP.Steinbach Could I post your comment as an answer with a reference to your comment? – Roman Byshko Dec 05 '11 at 04:06
  • @Beginner: certainly. :-) Cheers, – Cheers and hth. - Alf Dec 05 '11 at 04:07
  • 1
    @EtiennedeMartel - you mean about googling? Try it and erm ... scroll down to the images part. I seriously had no idea that was an actual thing (and I'm no prude). – Brian Roach Dec 05 '11 at 04:07
  • Related: http://stackoverflow.com/q/32606023/2020827 – sergej Oct 19 '16 at 13:45

8 Answers8

29

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

In C++

#include <cstring>

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

For Example:
string.h becomes cstring
stdio.h becomes cstdio and so on...


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:

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.

While 21.7 Null-terminated sequence utilities states:

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.

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

D.6 C standard library headers

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.

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>

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

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 ]

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.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 5
    @julio.alegria No. No no no no no. – Etienne de Martel Dec 05 '11 at 04:01
  • I meant, it's possible (just re-checked) – juliomalegria Dec 05 '11 at 04:04
  • @julio.alegria Yes, just like it's possible to do C in C++. Doesn't mean it's a good idea. – Etienne de Martel Dec 05 '11 at 04:05
  • 4
    @julio.alegria: **It is possible does not mean it is correct**, is an important trait of C++ programming language that you should learn about. – Alok Save Dec 05 '11 at 04:06
  • I actually know that trait, that's some of the reasons I migrated from C++ .. possible should mean correct (in the perfect language) – juliomalegria Dec 05 '11 at 04:10
  • 2
    @Als et al: using [cstring] as an *alternative* to [string.h] has no advantages and some severe disadvantages, like code failing to compile with other compiler. So in the either-or view, the only sane choice is [string.h]. I'm not sure if it has any practical adantage to include both. Maybe. But for just 1, then [string.h]. Cheers, – Cheers and hth. - Alf Dec 05 '11 at 04:12
  • @Als: Being possible doesn't mean incorrect either. Your post doesn't explain *why* one should use `cstring` over `string.h`. – Nicol Bolas Dec 05 '11 at 04:17
  • @AlfP.Steinbach: Under what circumstances would code fail to compile with `cstring`? Obviously if code isn't written to actually use those defines from the `std` namespace it won't work, but that's no different from just including the wrong header. It seems to me that code is no more likely to fail to compile across compilers with `cstring` than `string.h`. At the very least, some evidence would be good. – Nicol Bolas Dec 05 '11 at 04:18
  • 3
    @Nicol: I already gave an example. But anyway, code that uses any [string.h] function unqualified, such as `strlen`, *may* compile with [cstring], and probably will compile. For in C++11 [cstring] is allowed to litter the global namespace at will. With some other compiler and a cleaner [cstring] then the conventional (should I say habitual?) call fails to compile. With C++03 [cstring] was not allowed to pollute the global namespace in this way, and that was the *whole point* of the header. However, AFAIK nobody implemented that, so that it remained completely pointless... Pretty ironic. – Cheers and hth. - Alf Dec 05 '11 at 04:22
  • @AlfP.Steinbach: Thanks for the comments.I took some time to dig in to the standard to get the relevant quotes being caught up in some things at work, but I have updated the answer with relevant quotes and indeed I stand corrected. – Alok Save Dec 06 '11 at 04:14
6

There is a subtle difference between string.h and cstring

Answer of Alf P. Steinbach (can be found as a comment to the asked question):

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.

Community
  • 1
  • 1
Roman Byshko
  • 8,591
  • 7
  • 35
  • 57
  • 2
    `because code that e.g. uses just strlen may work fine with one compiler, then fail to compile with another compiler.` And I've found code that compiles under Visual Studio without warning or error will fail in GCC, because some VS headers will implicitly include things like `memcpy` while GCC won't. So I don't see how improper use of a header is a reason to pick one over the other; you're not guaranteeing yourself anything. If you include the `c*` version, then you should be using the `std::` namespace qualified names. And if you're not, then you get what you deserve. – Nicol Bolas Dec 05 '11 at 04:22
  • @NicolBolas You certainly have more expertise then me. I think the advantage of using string.h is just to be on the safe side. Yes, this will put all symbols of string.h in the global namespace, but the same can happen with cstdio. So why bother? – Roman Byshko Dec 05 '11 at 04:25
  • Did you see bames53's answer? – Nicol Bolas Dec 05 '11 at 04:51
  • NicolBolas Only now... This seem strange to me. How could @AlfP.Steinbach be so sure? – Roman Byshko Dec 05 '11 at 04:58
  • @Beginner: because the ISO C++ standard says so. barnes53 writes, correctly, that "The C++ version of the header actually has some differences from the C version.". That refers to C++'s [string.h], not a difference between [cstring] and [string.h]. Cheers & hth., – Cheers and hth. - Alf Dec 05 '11 at 05:11
  • @Nicol: you argue that because it's possible to create problems by forgetting to include a needed header, one should invite problems by using a known problematic header. after all, with problems here, and there, and everywhere, what's a few more, hey? however, that's not very convincing to me, i'm sorry to inform you. – Cheers and hth. - Alf Dec 05 '11 at 05:14
  • @AlfP.Steinbach So there are *3* files? `string.h` for С, `string.h` for C++ and `cstring` for C++??? – Roman Byshko Dec 05 '11 at 05:14
  • @Beginner: In principle yes there are 3 headers, namely [string.h] for C and [string.h] and [cstring] for C++. However, with e.g. Visual C++ styling itself as a "C/C++ Optimizing Compiler" you can be fairly sure that the [string.h] *file* is the same for both, but possibly with preprocessor based adaptions to the language it's used for. Lemme check... Yes. For example, the Visual C++ [string.h] defines `NULL` differently depending on whether the language is C or C++, namely as `0` for C++ and as `((void *)0)` for C. Cheers & hth., – Cheers and hth. - Alf Dec 05 '11 at 05:23
  • @AlfP.Steinbach Thank you very much, later I will try to gather *all* the info scattered in the comments and put it clear in one place. – Roman Byshko Dec 05 '11 at 05:26
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 .

Jagannath
  • 3,995
  • 26
  • 30
  • 2
    "In C++, C language headers are defined under the namespace std" <- that's incorrect – Cheers and hth. - Alf Dec 05 '11 at 05:08
  • 1
    @Alf P. Steinbach, I thought the c-style libraries are implemented under std namespace in C++. This link says so as well http://www.cplusplus.com/reference/clibrary/ – Jagannath Dec 05 '11 at 09:17
  • You can use that site as quick-help thing, but not as a reference. Besides, the link you refer to says "Every element of the library is defined within the std namespace" *about the cxxxx headers*, which is almost correct, but is not what you think it says. The C++ standard is the reference. The current standard is C++11. It's not cheap, but happily the N3290 draft is identical and was public a short time (if you should happen to get it later, like now, it would be illegal, he he). – Cheers and hth. - Alf Dec 05 '11 at 09:29
4

You can use string.h for both 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.

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

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

Googol
  • 174
  • 4
2

Apparently cstring is for C++ and string.h is for 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.

Deqing
  • 14,098
  • 15
  • 84
  • 131
2

<string.h> is C Header ,used for manipulation of NULL Terminated Character Array ~ Loosely string . <string> is C++ provides which has more convenient and advanced manipulation of strings (characters). <cstring> is C++ header providing backward combability with C type Strings.

<cstring> provide c string function in function Manner like string1 = string2.c_str(); Also has useful/basic/vintage functions like strcpy(), strlen() provided <string.h> C style which is by seceded by C++ style copy() , size() .

<string.h> is declared in

Global NameSpace

meanwhile , <cstring> is declared in

Standard (std) NameSpace

.

Nalisan
  • 21
  • 1
  • 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.

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.

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.

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

bames53
  • 86,085
  • 15
  • 179
  • 244
  • "prevents things like template specialization from working on those types" << Could you give an example of what you're trying to say here? On the surface of it, it doesn't make sense. – Cheers and hth. - Alf Dec 05 '11 at 05:17
  • Thanks for the example, now I understand what you *mean*. E.g. that in C++ `wchar_t` is a built-in type. Regarding the global namespace thing, see my answer. Cheers, – Cheers and hth. - Alf Dec 05 '11 at 09:34
0

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>

This was done to maintain compatibility with C. Try it yourself by including <cstring> and calling both memcpy() and std::memcpy().

CyclicUniverse
  • 133
  • 1
  • 5