C Programming/Libraries

From Wikibooks, the open-content textbooks collection

Jump to: navigation, search
Previous: Preprocessor Index Next: Standard libraries

A library in C is merely a group of functions and declarations. The library has an interface expressed in a file with a .h extension and an implementation expressed in a file with a .c extension (which may be precompiled or otherwise inaccessible). The "h" in .h stands for "header" as many include files could be at the top of a source file.

Libraries may call functions in other libraries such as the Standard C or math libraries to do various tasks.

For example, suppose you want to write a function to parse arguments from the command line. Arguments on the command line could be by themselves:

    -i

have an optional argument that is concatenated to the letter:

    -ioptarg

or have the argument in a separate argv-element:

    -i optarg

Suppose you want the ability to bunch switches in one argv-element as well. Anyway, after much writing, you come up with this:

 #include <stdio.h>              /* for fprintf() and EOF */
 #include <string.h>             /* for strchr() */
 #include "getopt.h"             /* consistency check */
 /* variables */
 int opterr = 1;                 /* getopt prints errors if this is on */
 int optind = 1;                 /* token pointer */
 int optopt;                     /* option character passed back to user */
 char *optarg;                   /* flag argument (or value) */
 /* function */
 /* return option character, EOF if no more or ? if problem.
    The arguments to the function:
    argc, argv - the arguments to the main() function. An argument of "--"
    stops the processing.
    opts - a string containing the valid option characters.
    an option character followed by a colon (:) indicates that
    the option has a required argument.
  */
 int
 getopt (int argc, char **argv, char *opts)
 {
   static int sp = 1;            /* character index into current token */
   register char *cp;            /* pointer into current token */
   if (sp == 1)
     {
       /* check for more flag-like tokens */
       if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
         return EOF;
       else if (strcmp (argv[optind], "--") == 0)
         {
           optind++;
           return EOF;
         }
     }
   optopt = argv[optind][sp];
   if (optopt == ':' || (cp = strchr (opts, optopt)) == NULL)
     {
       if (opterr)
         fprintf (stderr, "%s: invalid option -- '%c'\n", argv[0], optopt);
       /* if no characters left in this token, move to next token */
       if (argv[optind][++sp] == '\0')
         {
           optind++;
           sp = 1;
         }
       return '?';
     }
   if (*++cp == ':')
     {
       /* if a value is expected, get it */
       if (argv[optind][sp + 1] != '\0')
         /* flag value is rest of current token */
         optarg = argv[optind++] + (sp + 1);
       else if (++optind >= argc)
         {
           if (opterr)
             fprintf (stderr, "%s: option requires an argument -- '%c'\n",
                      argv[0], optopt);
           sp = 1;
           return '?';
         }
       else
         /* flag value is next token */
         optarg = argv[optind++];
       sp = 1;
     }
   else
     {
       /* set up to look at next char in token, next time */
       if (argv[optind][++sp] == '\0')
         {
           /* no more in current token, so setup next token */
           sp = 1;
           optind++;
         }
       optarg = 0;
     }
   return optopt;
 } 
 /* END OF FILE */

The implementation would be the above "getopt.c" file. The interface would be the following "getopt.h" file:

 #ifndef GETOPT_H
 #define GETOPT_H
 /* exported variables */
 extern int opterr, optind, optopt;
 extern char *optarg;
 /* exported function */
 int getopt(int, char **, char *);
 #endif
 /* END OF FILE */

All the programmer that is supposed to use this library sees (if he doesn't want to or can't look at the implementation) is the interface and the documentation that the library programmer wrote. The documentation should say that neither pointer can be null (or why would you be using the getopt function anyway?) and state what each parameter is for and the return value. The programmer that uses this library is not interested in the implementation of the library (unless the implementation has a bug, in which case he would want to complain somehow).

Both the implementation of this library (this ".c" file), and every program that uses this library (also ".c" files) should have a line saying "#include "getopt.h"" to refer to the corresponding interface for this library (this ".h" file). The main ".c" file -- the one that contains the main() function -- may refer to dozens of interfaces.

[edit] further reading

Previous: Preprocessor Index Next: Standard libraries
In other languages