26B. Standard Operations on Null-Terminated Strings

The following are available if you include <cstring>. Type size_t is equivalent to unsigned int.

size_t strlen(const char* s)

strlen(s) returns the length of null-terminated string s. The length does not count the null character. For example, strlen("rabbit") = 6.

Note. strlen finds the length by scanning through the null-terminated string looking for the null character. So computing strlen(s) takes time that is proportional to the length of the s. Avoid computing strlen(s) over and over for the same string s in the same function. That violates the standards for this course.


int strcmp(const char* s, const char* t )

Do not compare strings using ==. If s and t have type char* then expression s == t is true if s and t are the same pointer. It does not look at the characters in either of the strings.

Function strcmp compares strings s and t for alphabetical ordering or for equality by examining their characters. strcmp(s,t) returns an integer r with the following properties.

r < 0 if s comes before t
r = 0 if s and t are equal
r > 0 if s comes after t

For example, strcmp("cat", "cab") > 0 since "cat" comes after "cab" in alphabetical order.

Alphabetical ordering is determined by character codes. Since 'Z' has code 90 and 'a' has code 97, Z comes before a in the alphabetical ordering used by strcmp.

Here is how a former student asked whether string command was equal to "-t".
  if(command[0] == '-' &&
     command[1] == 't' &&
     command[2] == '\0')
  {
    …
That is clumsy and difficult to read. How about this instead.
  if(strcmp(command, "-t") == 0)
  {
    …


int strcasecmp(const char* s, const char* t )

Strcasecmp is like strcmp, but it ignores the case of letters. So 'r' and 'R' are treated like the same character.

char* strcpy(char* dest, const char* src);

strcpy(dest, src) copies null-terminated string src into array dest and null-terminates dest. The caller must ensure that there is enough room in array dest for the entire string plus the null character at the end.

The return value of strcpy(dest, src) is dest. However, the standards for this course require you not to make use of the value returned by strcpy.


char* strncpy(char* dest, const char* src, size_t n);

strncpy(dest, src, n) is like strcpy(dest, src), but array dest has size n, and no more than that many characters are copied. (If there is not room, no null character is stored in dest.) Do not make use of the result returned by strncpy.

char* strcat(char* dest, const char* src);

strcat(dest, src) copies string src to the end of the string in array dest, adding a null character to the end.

For example, suppose that dest and src start out as follows.

After doing strcat(dest, src), the picture changes to the following.

The value returned by strcat(dest, src) is dest. However, the standards for this course require that you not make use of the result returned by strcat.

There is a common misconception about strcat. Statement

  char* c = strcat(a,b);
does not set c to the concatenation of string a followed by b. It adds b to the end of the string in array a. So what is in array a is changed. Strcat does not allocate any memory. (This is one reason that the standards require you not to make use of the result returned by strcat.)


char* strncat(char* dest, const char* src, size_t n);

This is like strcat(dest, src), but at most n characters are copied from src. Do not use the result returned by strncat.

char* strchr(const char* s, int c)

strchr(s, c) returns a pointer to the first occurrence of character c in null-terminated string s. If there is no such character, strchr(c, s) returns NULL.

(The type of strchr is a poor one. Since parameter s has type const char*, strchr should not be able to return a non-const pointer into array s, since that gives you a back-door way to modify a constant string. However, the library designers really wanted to provide two different functions:

  const char* strchr(const char* s, int c);
  char* strchr(char* s, int c);
That is possible in C++, but not in C. The type of strchr is a compromise that works in both C++ and C, relying on the programmer not to abuse it.)


char* strstr(const char* haystack, const char* needle)

strstr(haystack, needle) returns a pointer to the first occurrence of substring needle in string haystack, or returns NULL if there is none. Both haystack and needle must be null-terminated strings.

Strings are not automatically allocated

Arrays are not automatically allocated for you. Don't expect space for null-terminated strings to show up by magic. Consider the following.

  char* str;
  strcpy(str, "horse");
What does that do? Reading the description of strcpy above, you see that strcpy(A, B) copies null-terminated string B into array A. It does not create A. That is the caller's responsibility.

But variable str is uninitialized. It is a dangling pointer. Storing "horse" at whatever address happens to be in variable str is an error that can have terrible consequences to your program.

Exercises

  1. What is the value of strlen("frog")? Answer

  2. What is the value of strlen("frog" + 1)? Answer

  3. What is the value of L after the following?

      char S[10];
      strcpy(S, "camel");
      int L = strlen(S);
    
    Answer

  4. What does the following do?

      char* s;
      strcpy(s, "goat");
    
    Answer

  5. What does the following do?

      char s[9];
      strcpy(s, "goat");
      strcat(s, "horse");
    
    Answer

  6. What does the following do?

      char* s = strcat("frog", "legs");
    
    Answer