Computer Science 2611
Summer 2002
Laboratory Assignment 9

Date assigned: 6/12/02

The assignment

For this lab, write the following string manipulation functions. Do not use the functions in the string.h library for this assignment. (All of these functions have equivalents in the standard string library.) Test the functions in any way that you see fit, but test them thoroughly. Do not turn in untested functions! Make several tests of each function. Be sure to test unusual cases, such as empty strings. You can write an empty string in your program as "". Build up a test file that tests all of the functions thoroughly. Do not remove the tests for one of the functions when it works. Leave all of the tests in place. Design your test function so that it runs the tests automatically. Do not require user interaction to perform the tests.

Write your functions in a file called mystring.cc. Create a header file mystring.h that contains prototypes for the functions. Write your tester in another file. Be sure to include mystring.h in the tester. Turn in all three files. Be sure that your name is in every file.

Some functions were written in the lecture. You may feel free to use the lecture versions of those functions.

  1. strlen(s) should return the length of null-terminated string s. For example, strlen("abcd") = 4.

  2. strcpy(s,t) should copy null-terminated string t into array s. After doing strcpy(s,t), array s should hold the same string as array t, and s should be null-terminated. Assume that enough space is available in array s.

  3. strcat(s,t) should copy null-terminated string t to the end of null-terminated string s. For example,

        strcpy(s, "abcd");
        strcat(s, "xyz");
      
    should end with array s holding null-terminated string "abcdxyz". Function strcat should presume that enough room is available in array s.

  4. strcmp(s,t) should compare null-terminated strings s and t according to alphabetical order. strcmp(s,t) should return

    -1 if s comes before t in alphabetical order
    0 if s and t are identical
    1 if s comes after t in alphabetical order

    Think about how to compare strings. You start with the first character of each string. You only continue to the next character if those characters are the same.

    If s is a prefix of t (for example, if s is "abc" and t is "abcde"), then strcmp(s,t) should return -1. Similarly, if t is a prefix of s, then strcmp(s,t) should return 1.

    You should use the standard ascii ordering of characters. You can compare two characters using comparisons such as < and >. Note that this will cause strcmp("DD","aa") to return -1, since character 'D' has a smaller ascii code than character 'a'. That is ok.

  5. strchr(s,c) tells where character c occurs in string s. Make it return the index of the first occurrence of c in string s, or -1 if there is no such character in s. For example, strchr("abcd", 'b') = 1 since 'b' occurs at index 1 in "abcd". (Remember that the first character is at index 0.) Note that strchr("abcd", 'e') = -1 since character 'e' does not occur in string "abcd".

    Note: There is a standard library function called strchr that behaves similarly to this function, but not quite the same. It returns the memory address of the character rather than its index, and returns memory address 0 if the character does not occur in the string.

    Note: Function strchr should work correctly when character c is the null character. It should return the index where the null character is located (at the end of the string). Be careful about this, since it is easy to get wrong.

  6. strstr(s,t) returns the smallest index where string t occurs as a substring of string s. For example, strstr("abcde","cd") returns 2, since string "cd" occurs inside string "abcde" beginning at index 2. (Remember that the first character has index 0.) For another example, strstr("abcdcabcab",","cab") returns 4 since the first occurrence of "cab" occurs in "abcdcabcab" starting at index 4.

    If string t does not occur inside string s, then strstr(s,t) should return -1. If t is an empty string, then strstr(s,t) should return 0.

    You might find it useful to write a helper function here(s,t,k) that returns a boolean value telling you whether string t occurs in string s starting at index k.

    The standard string library contains a similar function. But instead of returning the index where t occurs in s, it returns the memory address of the first occurrence of t in s. If t does not occur in s, it return memory address 0.


Notes on testing

Expert programmers generally prefer tests that do not require user interaction whenever they can use them. Such tests are much less time-consuming to run, and so the programmers use them more often.

You can easily use tests that do not require user interaction. Just test your functions on some fixed strings. For example,

  cout << "Begin strchr tests.\n";
  i = strchr("abcd", 'c');
  cout << "Test 1. " << i << " should be 2\n";
  ...
performs one test of strchr. It prints the answer, requiring the user to check whether the answer is correct. You can even make the tester check its own answers, and be silent if all goes well. That way, to run the test you don't need to wade through a lot of uninteresting output. You see only the cases where something goes wrong. Write something like
  cout << "Begin strchr tests.\n";
  i = strchr("abcd", 'c');
  if(i != 2) cout << "Test 1. " << i << " should be 2\n";
  ...

Software designers develop a large body of tests like this for their software, and run all of the tests frequently to be sure that new changes have not ruined something that used to work. For example, Microsoft runs a full test of everything every night, letting the software developers inspect the results when they come back to work in the morning. Such test suites are called regression tests.