DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
Using programming tools

Program structure

The descriptions that follow use the line numbers within testcase to indicate their location. This is an example of correct programming structure.

  1 #include <stdio.h>
  2 #include <ctype.h>
  3 #include <string.h>
  4 
  5 /* Manifests for state machine to parse input line. */
  6 #define	WORD	0
  7 #define	IGNORE	1
  8 
  9 /* Globals, used by both subroutines. */
 10 char	*Words[BUFFERSIZE/2];			/* Worst case, single letters. */
 11 int	WordCount;
 12 
 13 /* Walk through the array of words, find those with the
 14  * matching character, printing them on stdout. Note that
 15  * the null character will match all words.  */
 16 void PrintWords(wc, match)
 17 int	wc;				/* Number of words in Words[] */
 18 char	match;				/* Attempt to match this character. */
 19 {	
 20 	register int	ix;		/* Index in Words[]. */
 21 	register char	*cp;		/* Pointer for searching. */
 22 	for (ix = 0; ix < wc; ix++) {
 23 		cp = Words[ix];
 24 		/* Try to match the given character.
 25 		 * Scan the word, attempting to match,
 26 		 * or until the end of the word is found.  */
 27 		while ((*cp) && (*cp++ != match))
 28 		    ++cp;
 29 		if (*cp == match) /* Found a match? Write the word on stdout. */
 30 			(void) printf("%s\n", Words[ix]);
 31 	}
 32 	return;
 33 }
 34 
 35 
 36 /* Find words in the given buffer. The Words[] array is set
 37  * to point at words in the buffer, and the buffer modified
 38  * with null characters to delimit the words.  */
 39 int	GetWords(buf)
 40 char	buf[];				/* The input buffer. */
 41 {	
 42 	register char	*cp;		/* Pointer for scanning. */
 43 	int	end = strlen(buf);	/* Length of the buffer. */
 44 	register int	wc = 0;		/* Number of words found. */
 45 	int	state = IGNORE;		/* Current state. */
 46 	/* For each character in the buffer. */
 47 	for (cp = &buf[0]; cp < &buf[end]; cp++) {
 48 		/* A simple state machine to process
 49 		 * the current character in the buffer.
 50 		 */
 51 		switch (state) {
 52 		case IGNORE:
 53 			if (!isspace(*cp)) {
 54 				Words[wc++] = cp; /* Just started a word? Save it. */
 55 				state = WORD; /* Reset the state. */
 56 			}
 57 			break;
 58 		case WORD:
 59 			if (isspace(*cp)) {
 60 				*cp = '\0'; /* Just completed a word? terminate it. */
 61 				state = IGNORE; /* Reset the state. */
 62 			}
 63 			break;
 64 		}
 65 	}
 66 	return wc; /* Return the word count. */
 67 }
 68 
 69 
 70 
 71 int	main(argc, argv)
 72 int	argc;
 73 char	*argv[];
 74 {
 75 	char	buf[BUFFERSIZE], match;
 76 	/* Check command line arguments. */
 77 	if (argc < 2)
 78 		match = ' ';
 79 		/* No command line argument, match all words. */
 80 	else
 81 		match = *++argv[1];	/* Match the char after the first - */
 82 	/* Until no more input on stdin. */
 83 	while (gets(buf) != (char *)NULL) {
 84 		WordCount = GetWords(buf); /* Parse the input buffer. */
 85 		PrintWords(WordCount, match);  /* Print the matching words. */
 86 	}
 87 	return(0);  /* Return success to the shell. */
 88 }

Lines 1-3
Begin the code with #include statements for the header files that are required. Each section (S) page lists the header files that are required for that particular call; use a #include line for each one that is needed by the calls you are using.

There are some rules about the order in which header files are included; see ``Header files''. Application-specific header files should always be included after the standard header files.


Lines 74-91
The main() routine controls the order in which the routines execute. It is best to keep main() fairly succinct. Keep complex functionality in subroutines, located either before or after main(). This makes it easier to look at main() to get the general notion of program flow. If the application has several programs that call some of the same routines, those shared routines can be located in an archive or shared library for retrieval in all programs.

Line 74
The argc and argv parameters to main() capture arguments given on the command line. When a program begins execution, argc contains the argument count and argv is an array of pointers to the argument values. An argument is stored as a null-terminated string. The argument count is never less than 0.

Lines 18-70
Subroutines are coded outside the main() routine. Some people prefer to put them before main(), and others prefer to put them afterwards. Either approach works equally well.

Each subroutine should have a block comment preceding it to describe the subroutine and provide information about any non-obvious coding that may have been used. Well-written comments will significantly reduce the effort required to maintain the code in the future. Good C programming style dictates that block comments are not spread over several lines to the right of the actual code. Comments can be put on the line with the code, but these should be short comments that are specific to that line of code, such as shown in lines 17 and 18.



Next topic: Header files
Previous topic: Program structure and guidelines

© 2003 Caldera International, Inc. All rights reserved.
SCO OpenServer Release 5.0.7 -- 11 February 2003