eoln
boolean eoln (FILE *f)
Returns TRUE if the file pointer is currently at the end of the input line or FALSE otherwise. The argument f must be a pointer to a file structure that has been successfully opened for reading. Note that if a program reads from an input file character-by-character and reads the end-of-line sequence (generally either a carriage return character or a carriage return and line feed character), the eoln function will return FALSE, since it determines that the end of line has been reached by detecting the end-of-line sequence. It does not discard the end-of-line character(s), so to proceed to the next line of the file, you should call nextLine before the next read operation.
Example:
#include <fileio.h> #include <stdio.h> #include <stdlib.h>main () { FILE *in; int number;if ((in = fopen ("data.txt", "rt")) == NULL) perror ("Could not open input file data.txt"); exit (1); }/* read all numbers on the first line and print their squares */ while (!eoln (in)) { fscanf (in, "%d", &number); printf ("%d squared is %d\n", number * number); } fclose (in); }
fileEnd
boolean fileEnd (FILE *f)
Returns TRUE if the file pointer is currently at the end of the input file or FALSE otherwise. The argument f must be a pointer to a file structure that has been successfully opened for reading.
Example:
#include <fileio.h> #include <stdio.h> #include <stdlib.h>main () { FILE *in; int number;if ((in = fopen ("data.txt", "rt")) == NULL) perror ("Could not open input file data.txt"); exit (1); } /* read all numbers in the input file and print their squares */ while (!fileEnd (in)) fscanf (in, "%d", &number); printf ("%d squared is %d\n", number * number); } fclose (in); }
nextLine
void nextLine (FILE *f)
Moves the file pointer to the end of the current line of the input file so that the next read operation will read from the next line (if one exists) of the file. This is useful for discarding extraneous input on a line of an input file, but also for looping through a file line-by-line in conjunction with the fileEnd and eoln functions.
Example:
#include <stdio.h> #include <stdlib.h> #include <fileio.h>main () { FILE *in; char ch; int charCount, lineCount = 0;if ((in = fopen ("data.txt", "rt")) == NULL) perror ("Could not open input file data.txt"); exit (1); }while (!fileEnd (in)) { charCount = 0; while (!eoln (in)) { fscanf (in, " %c", &ch); ++charCount; } ++lineCount; printf ("Line %d contained %d non-blank characters\n", lineCount, charCount); nextLine (in); } fclose (in); }
Notes on the mathematical notion of sets:
A set is a mathematical abstraction which denotes an unordered collection of
items. A member or element of a set appears only once in the set, that
is, a set contains no duplicates. The standard mathematical notation for a set uses braces
to surround a list of the elements of the set. For example, {1 2 3} denotes the set of
integers greater than 0 and less than 4. Since sets are unordered, the set {1 2 3} and the
set {3 2 1} are identical. Most often, a set contains values from a given base or
component type. The example given has a component type of integer. The universe set
is the set that contains all the possible values of a particular component type.
Obviously, in mathematical terms, it is impossible to list the universe set whose base
type is integer, since it contains an infinite number of members. We could certainly list
the universe set whose base type is capital letters: {A B C D E F G H I J K L M N O P Q R
S T U V W X Y Z}. The number of members that a set contains is its cardinality.
Thus the set in the first example, {1 2 3}, has a cardinality of three, the universe set
of integers has infinite cardinality, and the set of all capital letters has a cardinality
of 26. The empty set, a set with no members, denoted as {} or phi, has a
cardinality of zero.
A description of the most common set operations follows:
Notes on sets as implemented in the sets library
Because of the inherent limitations of computers and for reasons of simplicity of implementation and efficiency, the set data type implemented in the set library differs somewhat from the mathematical notion of sets. First, all elements of a set must be of the same data type and only certain component types are permissible. The component types for sets are int, char, and enumerated types. Specifically, sets cannot contain members of type float. Furthermore, although components may be integers, the universe set of integers contains only numbers between 0 and 1023.
The sets library declares a type name for set variables: set. Note
that this type name does not specify the component type of the elements of the set. The
component type is implicit, determined by the elements that you add to the set variable.
To declare a set variable, you may use the type name just as you would any other type
name. For example:
set mySet;
declares a set variable named mySet which you could use to contain
elements of type int, char, or an enumerated type.
When you declare a variable of type set, it contains garbage, just as any other declared variable. Before you use the set, you must initialize it. Two operations, emptySet and addElems serve to initialize a set variable. The library also includes a print operation to print a set, but if the base type is an enumerated type, the print routine will print the elements as integers, rather than as the symbolic enumerated type values, so in this case, it would be better to write your own print routine to print each element of the set.
You should also take special note of the fact that although the braces used to denote sets in mathematics also exist in C, you cannot use braces in C to specify a set. In other words, be careful to avoid the temptation of trying to assign a value to a set variable using a statement like mySet = {1 2 3}; since it will not work.
Operations
emptySet
set emptySet ()
Creates and returns a set with no elements.
Example:
#include <sets.h>main () { set mySet = emptySet (); /* initializes mySet to the empty state */... }
addElems
set addElems (set s, int numElems, ...)
Adds numElems elements to an existing set s and returns the resulting set. This routine is mainly useful for initializing a set that must contain certain elements. The ... argument in the function signature stands for a list of parameters that specify the elements to add to the set. It is essential that the number of parameters in this list be exactly the same as the numElems parameter or the results will be unpredictable and undesirable. addElems does not alter the input parameter s, so it is important to assign the result of the function call to a set variable.
Example:
#include <sets.h>main () { set mySet = addElems (emptySet (), 3, 'a', 'b', 'c'); /* initialize mySet to the empty set and add elements 'a', 'b', and 'c'. after this line executes, mySet is {'a' 'b' 'c'} */ ... }
setUnion
set setUnion (set s1, set s2)
Returns the union of sets s1 and s2.
Example:
#include <sets.h>main () { set s1 = addElems (emptySet (), 3, 'a', 'b', 'c'), s2 = addElems (emptySet (), 4, 'a', 'c', 'e', 'g'), s3;s3 = setUnion (s1, s2); /*s3 is now {'a' 'b' 'c' 'e' 'g'} */ /*s1 and s2 remain unaltered */ }
intersection
set intersection (set s1, set s2)
Returns the intersection of sets s1 and s2.
Example:
#include <sets.h>main () { set s1 = addElems (emptySet (), 3, 'a', 'b', 'c'), s2 = addElems (emptySet (), 4, 'a', 'c', 'e', 'g'), s3;s3 = intersection (s1, s2); /*s3 is now {'a' 'c'} */ /*s1 and s2 remain unaltered */ }
difference
set difference (set s1, set s2)
Returns the difference s1 - s2.
Example:
#include <sets.h>main () { set s1 = addElems (emptySet (), 3, 'a', 'b', 'c'), s2 = addElems (emptySet (), 4, 'a', 'c', 'e', 'g'), s3;s3 = difference (s2, s1); /*s3 is now {'e' 'g'} */ /*s1 and s2 remain unaltered */ }
member
boolean member (set s, elem)
Returns TRUE if elem is a member of set s or FALSE otherwise. Since the component types of sets are implicit, it is possible for member to return TRUE when logically it should return FALSE. This can happen if elem is of a different type from the members of set s, but the underlying representation of elem and a member of s are the same. For instance, if s is the set {'a' 'b' 'c'}, the call member (s, 97); will return TRUE, since 97 is the ASCII code for 'a'.
Example:
#include <sets.h>#typedef enum {dog, cat, bird, goldfish, hamster} PetType;main () { set s1 = addElems (emptySet (), 3, dog, cat, hamster), s2 = addElems (emptySet (), 2, goldfish, bird), s3; PetType pet;s3 = difference (s1, s2); /* print the elements of s3: */ printf ("Set s3: { "); for (pet = dog, pet <= hamster; ++pet) { if (member (s3, pet)) switch (pet) { case dog: printf ("dog "); break; case cat: printf ("cat "); break; case bird: printf ("bird "); break; case goldfish: printf ("goldfish "); break; case hamster: printf ("hamster "); } } printf ("}\n"); }
equal
boolean equal (set s1, set s2)
Returns TRUE if s1 and s2 contain exactly the same elements. Since the base type of a set variable is implicit, it is important to use this function with care, since it may return TRUE if the arguments of the function contain elements that are of different base types but happen to have the same underlying representation. For example, if s1 is the set {'a' 'b' 'c'} and s2 is the set {97 98 99}, equal will return TRUE, since 97, 98, and 99 are the ASCII codes for the characters 'a', 'b', and 'c', respectively.
Example:
#include <sets.h>main () { set s1, s2;... /* initialize s1 and s2 */ if (equal (s1, s2)) printf ("Sets s1 and s2 are the same\n"); else printf ("Sets s1 and s2 are different\n");}
subset
boolean subset (set s1, set s2)
Returns TRUE if s1 is a subset of s2 or FALSE otherwise. The same precaution regarding component types applies here as for the member and equal functions.
Example:
#include <sets.h>main () { set s1, s2;... /* initialize s1 and s2 */ if (subset (s1, s2)) printf ("Set s1 is a subset of s2\n"); else printf ("Set s1 is not a subset of s2\n");}
properSubset
boolean properSubset (set s1, set s2)
Returns TRUE if s1 is a proper subset of s2 or FALSE otherwise. The same precaution regarding component types applies here as for the member and equal functions.
Example:
#include <sets.h>main () { set s1, s2;... /* initialize s1 and s2 */ if (properSubset (s1, s2)) printf ("Set s1 is a proper subset of s2\n"); else printf ("Set s1 is not a proper subset of s2\n");}
NOTE: You can use the subset and properSubset functions to determine whether one set is a (proper) superset of another by reversing the order of the arguments.
printSet
void printSet (set s, elemType t)
Prints the value of a set variable using brace notation. The argument t must be one of the following values: INT, CHAR, or ENUM and serves to indicate the component type of the elements of the set. Note that if the elements of the set are of an enumerated type, printSet will print the elements as integers. Thus, if you wish to print a set that contains members of an enumerated type, it is better to write your own print routine. The example for member shows a model for such a routine.
Example:
#include <sets.h>main () { set mySet = addElems (emptySet (), 4, 1, 10, 25, 6);printSet (mySet, INT); /* prints mySet as "{ 1 6 10 25 }" */}