Saturday, December 10, 2011

C Programming Lecture 15


Strings
A string in C is merely an array of characters. The length of a string is determined by a terminating null character: '\0'. So, a string with the contents, say, "abc" has four characters: 'a', 'b', 'c', and the terminating null character.
The terminating null character has the value zero.
The <string.h> Standard Header
Because programmers find raw strings cumbersome to deal with, they wrote the code in the <string.h> library. It represents not a concerted design effort but rather the accretion of contributions made by various authors over a span of years.
First, three types of functions exist in the string library:
  the mem functions manipulate sequences of arbitrary characters without regard to the null
     
character;
  the str functions manipulate null­terminated sequences of characters;
  the strn functions manipulate sequences of non­null characters.

The more commonly­used string functions
The nine most commonly used functions in the string library are:
  strcat ­ concatenate two strings
  strchr ­ string scanning operation
  strcmp ­ compare two strings
  strcpy ­ copy a string
  strlen ­ get string length
  strncat ­ concatenate one string with part of another


  strncmp ­ compare parts of two strings
  strncpy ­ copy part of a string
  strrchr ­ string scanning operation

The strcat function
char  *strcat(char  *  restrict  s1,  const  char  *  restrict  s2);
The strcat() function shall append a copy of the string pointed to by s2 (including the
terminating null byte) to the end of the string pointed to by s1. The initial byte of s2 overwrites the null byte at the end of s1. If copying takes place between objects that overlap, the behavior is
undefined. The function returns s1.
This function is used to attach one string to the end of another string. It is imperative that the first string (s1) have the space needed to store both strings.
Example:
#include  <stdio.h>
#include  <string.h>
static  const  char  *colors[]  =
{"Red","Orange","Yellow","Green","Blue","Purple"  };
static  const  char  *widths[]  =  {"Thin","Medium","Thick","Bold"  };
char  *penText;
penColor  =  3;  penThickness  =  2;
strcpy(penText,  colors[penColor]);
strcat(penText,  colors[penThickness]);
printf("My  pen  is  %s\n",  penText);  //  prints  'My  pen  is  GreenThick'
Before calling strcat(), the destination must currently contain a null terminated string or the
first character must have been initialized with the null character (e.g. penText[0] =  '\0';).

The following is a public­domain implementation of strcat:
#include  <string.h>
/*  strcat  */
char  *(strcat)(char  *restrict  s1,  const  char  *restrict  s2)
{
char  *s  =  s1;
/*  Move  s  so  that  it  points  to  the  end  of  s1.          */
while  (*s  !=  '\0')
s++;
/*  Copy  the  contents  of  s2  into  the  space  at  the  end  of  s1.         */
strcpy(s,  s2);
return  s1;
}

The strchr function
char  *strchr(const  char  *s,  int  c);
The strchr() function shall locate the first occurrence of c (converted to a char) in the string pointed to by s. The terminating null byte is considered to be part of the string. The function returns the location of the found character, or a null pointer if the character was not found.
This function is used to find certain characters in strings.
At one point in history, this function was named index. The strchr name, however cryptic, fits the general pattern for naming.
The following is a public­domain implementation of strchr:
#include  <string.h>
/*  strchr  */
char  *(strchr)(const  char  *s,  int  c)
{
/*  Scan  s  for  the  character.    When  this  loop  is  finished,
     
s  will  either  point  to  the  end  of  the  string  or  the
     
character  we  were  looking  for. */
while  (*s  !=  '\0'  &&  *s  !=  (char)c)
       
s++;
return  (  (*s  ==  c)  ?  (char  *)  s  :  NULL  );
}

The strcmp function
int  strcmp(const  char  *s1,  const  char  *s2);
A rudimentary form of string comparison is done with the strcmp() function. It takes two strings as arguments and returns a value less than zero if the first is lexographically less than the second, a
value greater than zero if the first is lexographically greater than the second, or zero if the two
strings are equal. The comparison is done by comparing the coded (ascii) value of the chararacters, character by character.
This simple type of string comparison is nowadays generally considered unacceptable when sorting lists of strings. More advanced algorithms exist that are capable of producing lists in dictionary
sorted order. They can also fix problems such as strcmp() considering the string "Alpha2" greater than "Alpha12". What we're saying is, don't use this strcmp() alone for general string sorting in any commercial or professional code.
The strcmp() function shall compare the string pointed to by s1 to the string pointed to by s2.
The sign of a non­zero return value shall be determined by the sign of the difference between the
values of the first pair of bytes (both interpreted as type unsigned  char) that differ in the
strings being compared. Upon completion, strcmp() shall return an integer greater than, equal to,
or less than 0, if the string pointed to by s1 is greater than, equal to, or less than the string pointed
to by s2, respectively.
Since comparing pointers by themselves is not practically useful unless one is comparing pointers within the same array, this function lexically compares the strings that two pointers point to.
This function is useful in comparisons, e.g.
if  (strcmp(s,  "whatever")  ==  0)  /*  do  something  */
       
;
Because the type of string comparison done by strcmp() is rather simple minded, when it is used to sort lists of strings, the lists are often not sorted as one would expect. It is generally considered
unacceptable
 to use strcmp in commercial software for general sorting of lists of strings. Better
comparison algorithms exist which result in string lists being sorted in the order they would appear in a dictionary, and can deal with problems such as making sure that "Alpha2" compares as less than "Alpha12". (In the previous example, "Alpha2" compares greater than "Alpha12"
because '2' comes after '1' in the character set.)
The collating sequence used by strcmp() is equivalent to the machine's native character set. The only guarantee about the order is that the digits from '0' to '9' are in consecutive order.






The following is a public­domain implementation of strcmp:
#include  <string.h>
/*  strcmp  */
int  (strcmp)(const  char  *s1,  const  char  *s2)
{
unsigned  char  uc1,  uc2;
/*  Move  s1  and  s2  to  the  first  differing  characters
in  each  string,  or  the  ends  of  the  strings  if  they
are  identical.        */
while  (*s1  !=  '\0'  &&  *s1  ==  *s2)  {
s1++;
s2++;
}
/*  Compare  the  characters  as  unsigned  char  and
     
return  the  difference. */
uc1  =  (*(unsigned  char  *)  s1);
uc2  =  (*(unsigned  char  *)  s2);
return  ((uc1  <  uc2)  ?  ­1  :  (uc1  >  uc2));
}


The strcpy function
char  *strcpy(char  *restrict  s1,  const  char  *restrict  s2);
The strcpy() function shall copy the string pointed to by s2 (including the terminating null byte) into the array pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined. The function returns s1. No value is used to indicate an error.
Example:
#include  <stdio.h>
#include  <string.h>
static  const  char  *penType="round"; char  penText[20];
strcpy(penText,  penType);
Important: When you call this function, you must ensure that the destination is able to contain all
the characters in the source array. Not doing so can have very serious consequences including
compromising the security and integrity of your entire computer. This is also true with some of the
other functions such as strcat(). This is very unlikely and in most cases a problem will simply
result in the program crashing, or not functioning correctly. But this problem has been at the root of
many computer security problems that you may have read or heard about in recent times.
The s1 pointer must pointer to a buffer with enough space to store the string pointed to by s2, or
undefined
 behavior may result, including (but not limited to) monkeys flying out of your nose.
This function is used to copy one string to another, as direct assignment of pointers can be unwieldingly tricky.
The following is a public­domain implementation of strcpy:
#include  <string.h>
/*  strcpy  */
char  *(strcpy)(char  *restrict  s1,  const  char  *restrict  s2)
{
char  *dst  =  s1;
const  char  *src  =  s2;
/*  Do  the  copying  in  a  loop.       */
while  ((*dst++  =  *src++)  !=  '\0')






;
/*  Return  the  destination  string.            */
return  s1;
}


The strlen function
size_t  strlen(const  char  *s);
The strlen() function shall compute the number of bytes in the string to which s points, not
including the terminating null byte. It returns the number of bytes in the string. No value is used to indicate an error.
The following is a public­domain implementation of strlen:
#include  <string.h>
/*  strlen  */
size_t  (strlen)(const  char  *s)
{
char  *p  =  s;
/*  Loop  over  the  data  in  s.       */
while  (*p  !=  '\0')
p++;
return  (size_t)(p  ­  s);
}

The strncat function
char  *strncat(char  *restrict  s1,  const  char  *restrict  s2,  size_t
n);
The strncat() function shall append not more than n bytes (a null byte and bytes that follow it are not appended) from the array pointed to by s2 to the end of the string pointed to by s1. The initial byte of s2 overwrites the null byte at the end of s1. A terminating null byte is always
appended to the result. If copying takes place between objects that overlap, the behavior is
undefined. The function returns s1.
The following is a public­domain implementation of strncat:
#include  <string.h>
/*  strncat  */
char  *(strncat)(char  *restrict  s1,  const  char  *restrict  s2,  size_t  n)
{
char  *s  =  s1;
/*  Loop  over  the  data  in  s1.       */
while  (*s  !=  '\0')
s++;
/*  s  now  points  to  s1's  trailing  null  character,  now  copy
up  to  n  bytes  from  s2  into  s1  stopping  if  a  null  character is  encountered  in  s2.
It  is  not  safe  to  use  strncpy  here  since  it  copies  EXACTLY  n characters,  NULL  padding  if  necessary. */
while  (n  !=  0  &&  (*s  =  *s2++)  !=  '\0')  {
       
n­­;
s++;
}
if  (*s  !=  '\0')
*s  =  '\0';
return  s1;
}






The strncmp function
int  strncmp(const  char  *s1,  const  char  *s2,  size_t  n);
The strncmp() function shall compare not more than n bytes (bytes that follow a null byte are
not compared) from the array pointed to by s1 to the array pointed to by s2. The sign of a non­zero return value is determined by the sign of the difference between the values of the first pair of bytes (both interpreted as type unsigned  char) that differ in the strings being compared. See
strcmp for an explanation of the return value.
This function is useful in comparisons, as the strcmp function is.
The
 following is a public­domain implementation of strncmp:
#include  <string.h>
/*  strncmp  */
int  (strncmp)(const  char  *s1,  const  char  *s2,  size_t  n)
{
unsigned  char  uc1,  uc2;
/*  Nothing  to  compare?    Return  zero.      */
if  (n  ==  0)
return  0;
/*  Loop,  comparing  bytes.      */
while  (n­­  >  0  &&  *s1  ==  *s2)  {
/*  If  we've  run  out  of  bytes  or  hit  a  null,  return  zero
     
since  we  already  know  *s1  ==  *s2. */
if  (n  ==  0  ||  *s1  ==  '\0')
return  0;
s1++;
s2++;
}
uc1  =  (*(unsigned  char  *)  s1);
uc2  =  (*(unsigned  char  *)  s2);
return  ((uc1  <  uc2)  ?  ­1  :  (uc1  >  uc2));
}

The strncpy function
char  *strncpy(char  *restrict  s1,  const  char  *restrict  s2,  size_t
n);
The strncpy() function shall copy not more than n bytes (bytes that follow a null byte are not
copied) from the array pointed to by s2 to the array pointed to by s1. If copying takes place
between objects that overlap, the behavior is undefined. If the array pointed to by s2 is a string that
is shorter than n bytes, null bytes shall be appended to the copy in the array pointed to by s1, until
n
 bytes in all are written. The function shall return s1; no return value is reserved to indicate an
error.
It is possible that the function will not return a null­terminated string, which happens if the s2 string is longer than n bytes.
The following is a public­domain version of strncpy:
#include  <string.h>
/*  strncpy  */
char  *(strncpy)(char  *restrict  s1,  const  char  *restrict  s2,  size_t  n)
{
char  *dst  =  s1;
const  char  *src  =  s2;
/*  Copy  bytes,  one  at  a  time.       */
while  (n  >  0)  {
n­­;
if  ((*dst++  =  *src++)  ==  '\0')  {
/*  If  we  get  here,  we  found  a  null  character  at  the  end
of  s2,  so  use  memset  to  put  null  bytes  at  the  end  of
s1.    */
memset(dst,  '\0',  n);
break;
}
}
return  s1;
}

The strrchr function
char  *strrchr(const  char  *s,  int  c);
strrchr is similar to strchr, except the string is searched right to left.
The strrchr() function shall locate the last occurrence of c (converted to a char) in the string pointed to by s. The terminating null byte is considered to be part of the string. Its return value is similar to strchr's return value.
At one point in history, this function was named rindex. The strrchr name, however cryptic, fits the general pattern for naming.
The following is a public­domain implementation of strrchr:
#include  <string.h>
/*  strrchr  */
char  *(strrchr)(const  char  *s,  int  c)
{
const  char  *last  =  NULL;
/*  If  the  character  we're  looking  for  is  the  terminating  null,
   
we  just  need  to  look  for  that  character  as  there's  only  one
     
of  them  in  the  string. */
if  (c  ==  '\0')
return  strchr(s,  c);
/*  Loop  through,  finding  the  last  match  before  hitting  NULL.            */
while  ((s  =  strchr(s,  c))  !=  NULL)  {
last  =  s;
s++;
}
return  (char  *)  last;
}

The less commonly­used string functions
The less­used functions are:
  memchr ­ Find a byte in memory
  memcmp ­ Compare bytes in memory
  memcpy ­ Copy bytes in memory
  memmove ­ Copy bytes in memory with overlapping areas
  memset ­ Set bytes in memory
  strcoll ­ Compare bytes according to a locale­specific collating sequence
  strcspn ­ Get the length of a complementary substring
  strerror ­ Get error message
  strpbrk ­ Scan a string for a byte
  strspn ­ Get the length of a substring
  strstr ­ Find a substring
  strtok ­ Split a string into tokens
  strxfrm ­ Transform string

Copying functions

The memcpy function
void  *memcpy(void  *  restrict  s1,  const  void  *  restrict  s2,  size_t
n);
The memcpy() function shall copy n bytes from the object pointed to by s2 into the object
pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined. The function returns s1.
Because the function does not have to worry about overlap, it can do the simplest copy it can. The following is a public­domain implementation of memcpy:
#include  <string.h>
/*  memcpy  */
void  *(memcpy)(void  *  restrict  s1,  const  void  *  restrict  s2,  size_t  n)
{
char  *dst  =  s1;
const  char  *src  =  s2;
/*  Loop  and  copy.    */
while  (n­­  !=  0)
*dst++  =  *src++; return  s1;
}


The memmove function
void  *memmove(void  *s1,  const  void  *s2,  size_t  n);
The memmove() function shall copy n bytes from the object pointed to by s2 into the object
pointed to by s1. Copying takes place as if the n bytes from the object pointed to by s2 are first copied into a temporary array of n bytes that does not overlap the objects pointed to by s1 and s2, and then the n bytes from the temporary array are copied into the object pointed to by s1. The
function returns the value of s1.
The easy way to implement this without using a temporary array is to check for a condition that would prevent an ascending copy, and if found, do a descending copy.
The following is a public­domain implementation of memmove:
#include  <string.h>
/*  memmove  */
void  *(memmove)(void  *s1,  const  void  *s2,  size_t  n)
{
/*  note:  these  don't  have  to  point  to  unsigned  chars  */ char  *p1  =  s1;
const  char  *p2  =  s2;
/*  test  for  overlap  that  prevents  an  ascending  copy  */ if  (p2  <  p1  &&  p1  <  p2  +  n)  {
/*  do  a  descending  copy  */ p2  +=  n;
p1  +=  n;
while  (n­­  !=  0)
*­­p1  =  *­­p2;
}  else
while  (n­­  !=  0)
*p1++  =  *p2++;






return  s1;
}

Comparison functions

The memcmp function
int  memcmp(const  void  *s1,  const  void  *s2,  size_t  n);
The memcmp() function shall compare the first n bytes (each interpreted as unsigned  char) of
the object pointed to by s1 to the first n bytes of the object pointed to by s2. The sign of a non­zero
return value shall be determined by the sign of the difference between the values of the first pair of
bytes
 (both interpreted as type unsigned  char) that differ in the objects being compared.
The following is a public­domain implementation of memcmp:
#include  <string.h>
/*  memcmp  */
int  (memcmp)(const  void  *s1,  const  void  *s2,  size_t  n)
{
unsigned  char  *us1  =  (unsigned  char  *)  s1; unsigned  char  *us2  =  (unsigned  char  *)  s2; while  (n­­  !=  0)  {
if  (*us1  !=  *us2)
return  (*us1  <  *us2)  ?  ­1  :  +1;
us1++;
us2++;
}
return  0;
}


The strcoll and strxfrm functions
int  strcoll(const  char  *s1,  const  char  *s2);
size_t  strxfrm(char  *s1,  const  char  *s2,  size_t  n);
The ANSI C Standard specifies two locale­specific comparison functions.
The strcoll function compares the string pointed to by s1 to the string pointed to by s2, both interpreted as appropriate to the LC_COLLATE category of the current locale. The return value is similar to strcmp.
The strxfrm function transforms the string pointed to by s2 and places the resulting string into
the array pointed to by s1. The transformation is such that if the strcmp function is applied to the
two transformed strings, it returns a value greater than, equal to, or less than zero, corresponding to
the result of the strcoll function applied to the same two original strings. No more than n
characters are placed into the resulting array pointed to by s1, including the terminating null
character.
 If n is zero, s1 is permitted to be a null pointer. If copying takes place between objects
that
 overlap, the behavior is undefined. The function returns the length of the transformed string.
These functions are rarely used and nontrivial to code, so there is no code for this section.

Search functions

The memchr function
void  *memchr(const  void  *s,  int  c,  size_t  n);


The memchr() function shall locate the first occurrence of c (converted to an unsigned  char) in the initial n bytes (each interpreted as unsigned  char) of the object pointed to by s. If c is not found, memchr returns a null pointer.
The following is a public­domain implementation of memchr:
#include  <string.h>
/*  memchr  */
void  *(memchr)(const  void  *s,  int  c,  size_t  n)
{
const  unsigned  char  *src  =  s; unsigned  char  uc  =  c;
while  (n­­  !=  0)  {
  
if  (*src  ==  uc)
return  (void  *)  src;
src++;
}
return  NULL;
}


The strcspn, strpbrk, and strspn functions
size_t  strcspn(const  char  *s1,  const  char  *s2);
char  *strpbrk(const  char  *s1,  const  char  *s2);
size_t  strspn(const  char  *s1,  const  char  *s2);
The strcspn function computes the length of the maximum initial segment of the string pointed to by s1 which consists entirely of characters not from the string pointed to by s2.
The strpbrk function locates the first occurrence in the string pointed to by s1 of any character
from the string pointed to by s2, returning a pointer to that character or a null pointer if not found.
The strspn function computes the length of the maximum initial segment of the string pointed to by s1 which consists entirely of characters from the string pointed to by s2.
All of these functions are similar except in the test and the return value.
The following are public­domain implementations of strcspn, strpbrk, and strspn:
#include  <string.h>
/*  strcspn  */
size_t  (strcspn)(const  char  *s1,  const  char  *s2)
{
const  char  *sc1;
for  (sc1  =  s1;  *sc1  !=  '\0';  sc1++)
       
if  (strchr(s2,  *sc1)  !=  NULL)
return  (sc1  ­  s1);
return  sc1  ­  s1;                           /*  terminating  nulls  match  */
}

#include  <string.h> /*  strpbrk  */
char  *(strpbrk)(const  char  *s1,  const  char  *s2)
{
const  char  *sc1;
for  (sc1  =  s1;  *sc1  !=  '\0';  sc1++)
       
if  (strchr(s2,  *sc1)  !=  NULL)
return  (char  *)sc1;
return  NULL;                                /*  terminating  nulls  match  */
}

#include  <string.h>
/*  strspn  */
size_t  (strspn)(const  char  *s1,  const  char  *s2)
{
const  char  *sc1;
for  (sc1  =  s1;  *sc1  !=  '\0';  sc1++)
       
if  (strchr(s2,  *sc1)  ==  NULL)
return  (sc1  ­  s1);
return  sc1  ­  s1;                           /*  terminating  nulls  don't  match  */
}


The strstr function
char  *strstr(const  char  *s1,  const  char  *s2);
The strstr() function shall locate the first occurrence in the string pointed to by s1 of the
sequence of bytes (excluding the terminating null byte) in the string pointed to by s2. The function returns the pointer to the matching string in s1 or a null pointer if a match is not found. If s2 is an empty string, the function returns s1.
The following is a public­domain implementation of strstr:
#include  <string.h>
/*  strstr  */
char  *(strstr)(const  char  *s1,  const  char  *s2)
{
size_t  s2len;
/*  Check  for  the  null  s2  case.        */
if  (*s2  ==  '\0')
return  (char  *)  s1;
s2len  =  strlen(s2);
for  (;  (s1  =  strchr(s1,  *s2))  !=  NULL;  s1++)
       
if  (strncmp(s1,  s2,  s2len)  ==  0)
return  (char  *)  s1;
return  NULL;
}


The strtok function
char  *strtok(char  *restrict  s1,  const  char  *restrict  delimiters);
A sequence of calls to strtok() breaks the string pointed to by s1 into a sequence of tokens,
each of which is delimited by a byte from the string pointed to by delimiters. The first call in
the sequence has s1 as its first argument, and is followed by calls with a null pointer as their first
argument.
 The separator string pointed to by delimiters may be different from call to call.
The first call in the sequence searches the string pointed to by s1 for the first byte that is not
contained in the current separator string pointed to by delimiters. If no such byte is found, then there are no tokens in the string pointed to by s1 and strtok() shall return a null pointer. If such a byte is found, it is the start of the first token.
The strtok() function then searches from there for a byte (or multiple, consecutive bytes) that is
contained in the current separator string. If no such byte is found, the current token extends to the
end of the string pointed to by s1, and subsequent searches for a token shall return a null pointer. If
such a byte is found, it is overwritten by a null byte, which terminates the current token. The
strtok() function saves a pointer to the following byte, from which the next search for a token
shall start.
Each subsequent call, with a null pointer as the value of the first argument, starts searching from the saved pointer and behaves as described above.



The strtok() function need not be reentrant. A function that is not required to be reentrant is not required to be thread­safe.
Because the strtok() function must save state between calls, and you could not have two tokenizers going at the same time, the Single Unix Standard defined a similar function, strtok_r(), that does not need to save state. Its prototype is this:
char  *strtok_r(char  *s,  const  char  *delimiters,  char  **lasts);
The strtok_r() function considers the null­terminated string s as a sequence of zero or more text tokens separated by spans of one or more characters from the separator string delimiters. The argument lasts points to a user­provided pointer which points to stored information necessary for strtok_r() to continue scanning the same string.
In the first call to strtok_r(), s points to a null­terminated string, delimiters to a null­
terminated string of separator characters, and the value pointed to by lasts is ignored. The
strtok_r() function shall return a pointer to the first character of the first token, write a null
character into s immediately following the returned token, and update the pointer to which lasts
points.
In subsequent calls, s is a null pointer and lasts shall be unchanged from the previous call so that subsequent calls shall move through the string s, returning successive tokens until no tokens
remain. The separator string delimiters may be different from call to call. When no token
remains in s, a NULL pointer shall be returned.
The following public­domain code for strtok and strtok_r codes the former as a special case of the latter:
#include  <string.h> /*  strtok_r  */
char  *(strtok_r)(char  *s,  const  char  *delimiters,  char  **lasts)
{
char  *sbegin,  *send;
sbegin  =  s  ?  s  :  *lasts;
sbegin  +=  strspn(sbegin,  delimiters); if  (*sbegin  ==  '\0')  {
*lasts  =  "";
return  NULL;
}
send  =  sbegin  +  strcspn(sbegin,  delimiters);
if  (*send  !=  '\0')
*send++  =  '\0';
*lasts  =  send;
return  sbegin;
}
/*  strtok  */
char  *(strtok)(char  *restrict  s1,  const  char  *restrict  delimiters)
{
static  char  *ssave  =  "";
return  strtok_r(s1,  delimiters,  &ssave);
}

Miscellaneous functions
These functions do not fit into one of the above categories.

The memset function
void  *memset(void  *s,  int  c,  size_t  n);





The memset() function converts c into unsigned  char, then stores the character into the first n bytes of memory pointed to by s.
The following is a public­domain implementation of memset:
#include  <string.h>
/*  memset  */
void  *(memset)(void  *s,  int  c,  size_t  n)
{
unsigned  char  *us  =  s;
unsigned  char  uc  =  c;
while  (n­­  !=  0)
*us++  =  uc;
return  s;
}


The strerror function
char  *strerror(int  errorcode);
This function returns a locale­specific error message corresponding to the parameter. Depending on
the circumstances, this function could be trivial to implement, but this author will not do that as it
varies.
The Single Unix System Version 3 has a variant, strerror_r, with this prototype: int  strerror_r(int  errcode,  char  *buf,  size_t  buflen); This function stores the message in buf, which has a length of size buflen.
examples
To determine the number of characters in a string, the strlen() function is used.
#include  <stdio.h>
#include  <string.h>

int  length,  length2; char  *turkey;
static  char  *flower=  "begonia";
static  char  *gemstone="ruby  ";

length  =  strlen(flower);
printf("Length  =  %d\n",  length);  //  prints  'Length  =  7' length2  =  strlen(gemstone);

turkey  =  (char  *)malloc(  length  +  length2  +  1); if  (turkey)  {
strcpy(  turkey,  gemstone);
strcat(  turkey,  flower);
printf(  "%s\n",  turkey);  //  prints  'ruby  begonia' free(  turkey  );
}
Note that the amount of memory allocated for 'turkey' is one plus the sum of the lengths of the strings to be concatenated. This is for the terminating null character, which is not counted in the lengths of the strings. 

0 comments: