Here is a sample program that uses a variety of the important string commands provided by C. The program solves the following problem:

Problem: You are given a list of names that are separated by the word "end". For example:

Yifan Tang end
Brad Vander Zanden end
Nels Blank
Vander Zanden end
Your program should print:

  1. the longest name (i.e., the name with the longest length)
  2. the first name in alphabetical order

In the above input, "Nels Blake Vander Zanden" is the longest name and "Brad Vander Zanden" is the first name in alphabetical order. Note that names are typically comprised of multiple words separated by blank spaces, so you will need to use strcat to concatenate the words together to form a name. You will need to use the strlen function to determine the length of the longest string, strcmp to find the first name in alphabetical order and to determine when you have encountered an "end" token, and strcpy to save a copy of the longest length word and a copy of the first word in alphabetical order.


The Program

I have included some commentary at the end of this program.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_SINGLE_NAME 20
#define MAX_NAME 100

main() {
  char word[MAX_SINGLE_NAME];
  char name[MAX_NAME] = "";
  char longest[MAX_NAME] = "";
  char smallest[MAX_NAME] = "";
  
  /* read an initial word into name. I do not want to wait to initialize
     name until I am in the loop, because the first strcat
     statement will add a blank space to the front of the name. */
  scanf("%s", name);

  /* read words until EOF */
  while (scanf("%s", word) != EOF) {
    if (strcmp(word, "end") == 0) {
      if (strlen(name) > strlen(longest)) {
	strcpy(longest, name);
      }
      /* determine if the current name is the new smallest name */
      if (strcmp(smallest, "") == 0) {
 	strcpy(smallest, name);
      }
      else if (strcmp(name, smallest) < 0) {
	strcpy(smallest, name);
      }
      /* I used to copy an empty string to name to re-initialize it,
	 but I discovered that this was causing me to have a space
	 before the start of the first name, because strcat starts
	 by appending a space to the name. I thus changed the code
	 so that it now reads the next word directly into name. This
	 assumes that there will not be an empty name (i.e., there will
	 not be two consecutive "end" tokens in the input) */
      scanf("%s", name); /* start the next name */
    }
    /* concatenate words into a bigger name until I see an "end" token */
    else {
      strcat(name, " ");
      strcat(name, word);
    }
  }

  /* print longest name */
  printf("longest = %s\n", longest);
  /* print first name in alphabetical order */
  printf("smallest = %s\n", smallest);
  return(0);
}

Commentary

Here are some issues that I encountered or thought about as I developed the program:

  1. I initially developed the program without worrying about boundary conditions. Boundary conditions are special cases that occur at the start or end of the program (e.g., how do you initialize a variable), or that involve special cases in the input (e.g., how do you handle an empty file). By initially ignoring boundary conditions, I was able to focus on the main logic of the program, without worrying about the annoying, but important details of boundary conditions.

  2. Once I had written the initial code, I knew that I had not initialized many of the important variables, such as longest, smallest, and name. It is important to get variable initialization correct and as you will see, I did not get it entirely correct on my first try. I took a different approach to initializing each of these three variables: