String Headers

E

Eric

Hello

I have seen some code with #include<string.h> and some code with
#include<strings.h>.

However one is a symlink to the other.

My question is: what is the distinction between these headers?

[E]
 
E

Eric Sosman

Hello

I have seen some code with #include<string.h> and some code with
#include<strings.h>.

However one is a symlink to the other.

My question is: what is the distinction between these headers?

In the days before C was standardized, some implementations
had <string.h> and some had <strings.h> (and what they contained
tended to vary, too). Two decades ago the ANSI Standard chose
<string.h> as The Official Home for string-related declarations,
and went on to specify what <string.h> should contain.

Some implementations kept <strings.h> around for the benefit
of old code: Easier to add a symlink to the system than to endure
a zillion complaints about working programs that suddenly stopped
compiling. You've probably found a remnant of that policy.

Use <string.h> in new code, and whenever you happen to be
editing old code consider changing <strings.h> to <string.h> while
you're there.
 
J

James Kuyper

Hello

I have seen some code with #include<string.h> and some code with
#include<strings.h>.

However one is a symlink to the other.

My question is: what is the distinction between these headers?

string.h is a C standard library header. It's supposed to contain
declarations or definitions of the following items (Appendix B.23):
=====================================================================
size_t
NULL
void *memcpy(void * restrict s1,
const void * restrict s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
char *strcpy(char * restrict s1,
const char * restrict s2);
char *strncpy(char * restrict s1,
const char * restrict s2, size_t n);
char *strcat(char * restrict s1,
const char * restrict s2);
char *strncat(char * restrict s1,
const char * restrict s2, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
int strcmp(const char *s1, const char *s2);
int strcoll(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
size_t strxfrm(char * restrict s1,
const char * restrict s2, size_t n);
void *memchr(const void *s, int c, size_t n);
char *strchr(const char *s, int c);
size_t strcspn(const char *s1, const char *s2);
char *strpbrk(const char *s1, const char *s2);
char *strrchr(const char *s, int c);
size_t strspn(const char *s1, const char *s2);
char *strstr(const char *s1, const char *s2);
char *strtok(char * restrict s1,
const char * restrict s2);
void *memset(void *s, int c, size_t n);
char *strerror(int errnum);
size_t strlen(const char *s);
_ _STDC_WANT_LIB_EXT1_ _
errno_t
rsize_t
errno_t memcpy_s(void * restrict s1, rsize_t s1max,
const void * restrict s2, rsize_t n);
errno_t memmove_s(void *s1, rsize_t s1max,
const void *s2, rsize_t n);
errno_t strcpy_s(char * restrict s1,
rsize_t s1max,
const char * restrict s2);
errno_t strncpy_s(char * restrict s1,
rsize_t s1max,
const char * restrict s2,
rsize_t n);
errno_t strcat_s(char * restrict s1,
rsize_t s1max,
const char * restrict s2);
errno_t strncat_s(char * restrict s1,
rsize_t s1max,
const char * restrict s2,
rsize_t n);
char *strtok_s(char * restrict s1,
rsize_tsize_t strxfrm(char * restrict s1,
const char * restrict s2, size_t n);
void *memchr(const void *s, int c, size_t n);
char *strchr(const char *s, int c);
size_t strcspn(const char *s1, const char *s2);
char *strpbrk(const char *s1, const char *s2);
char *strrchr(const char *s, int c);
size_t strspn(const char *s1, const char *s2);
char *strstr(const char *s1, const char *s2);
char *strtok(char * restrict s1,
const char * restrict s2);
void *memset(void *s, int c, size_t n);
char *strerror(int errnum);
size_t strlen(const char *s);
_ _STDC_WANT_LIB_EXT1_ _
errno_t
rsize_t
errno_t memcpy_s(void * restrict s1, rsize_t s1max,
const void * restrict s2, rsize_t n);
errno_t memmove_s(void *s1, rsize_t s1max,
const void *s2, rsize_t n);
errno_t strcpy_s(char * restrict s1,
rsize_t s1max,
const char * restrict s2);
errno_t strncpy_s(char * restrict s1,
rsize_t s1max,
const char * restrict s2,
rsize_t n);
errno_t strcat_s(char * restrict s1,
rsize_t s1max,
const char * restrict s2);
errno_t strncat_s(char * restrict s1,
rsize_t s1max,
const char * restrict s2,
rsize_t n);
char *strtok_s(char * restrict s1,
rsize_t * restrict s1max,
const char * restrict s2,
char ** restrict ptr);
errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n)
errno_t strerror_s(char *s, rsize_t maxsize,
errno_t errnum);
size_t strerrorlen_s(errno_t errnum);
size_t strnlen_s(const char *s, size_t maxsize);

strings.h is not a C standard library header. It could be many different
things. If you're using a unix-like systems, one thing it could be is an
X/Open System Interfaces (XSI) extension. That header is supposed to
contain the following declarations
<http://pubs.opengroup.org/onlinepubs/009695399/toc.htm>:
==========================================================
int bcmp(const void *, const void *, size_t); (LEGACY )
void bcopy(const void *, void *, size_t); (LEGACY )
void bzero(void *, size_t); (LEGACY )
int ffs(int);
char *index(const char *, int); (LEGACY )
char *rindex(const char *, int); (LEGACY )
int strcasecmp(const char *, const char *);
int strncasecmp(const char *, const char *, size_t);

There's not a single item in common between those two files, other than
the fact that they both need a typedef for size_t. Creating a single
file to serve both purposes seems quite odd. What you've got might be
something else entirely. How well do the contents match those two lists?
 
A

Angel

Hello

I have seen some code with #include<string.h> and some code with
#include<strings.h>.

However one is a symlink to the other.

My question is: what is the distinction between these headers?

string.h is a C standard library header. It's supposed to contain
declarations or definitions of the following items (Appendix B.23):
=====================================================================
size_t
NULL
void *memcpy(void * restrict s1,
const void * restrict s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
char *strcpy(char * restrict s1, [...]

strings.h is not a C standard library header. It could be many different
things. If you're using a unix-like systems, one thing it could be is an
X/Open System Interfaces (XSI) extension. That header is supposed to
contain the following declarations
<http://pubs.opengroup.org/onlinepubs/009695399/toc.htm>:
==========================================================
int bcmp(const void *, const void *, size_t); (LEGACY )
void bcopy(const void *, void *, size_t); (LEGACY )
void bzero(void *, size_t); (LEGACY )
int ffs(int);
char *index(const char *, int); (LEGACY )
char *rindex(const char *, int); (LEGACY )
int strcasecmp(const char *, const char *);
int strncasecmp(const char *, const char *, size_t);

There's not a single item in common between those two files, other than
the fact that they both need a typedef for size_t. Creating a single
file to serve both purposes seems quite odd. What you've got might be
something else entirely. How well do the contents match those two lists?

Examining the situation on my Linux system, string.h contains both the
stuff you listed for string.h and strings.h, with the latter between
"#ifdef __USE_BSD" checks. The file strings.h contains only the
things you listed for it, with a check if they were already included
from string.h.

According to the manual page, the bcopy() function conforms to 4.3BSD,
so my guess is that glibc installs strings.h for backwards compatibility
with BSD source code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top