#include "fields.h",and then compile the program with:
gcc -I/mahogany/homes/plank/cs360/includeAlso when you link your object files to make an executable, you need to include /mahogany/homes/plank/cs360/objs/fields.o. This assumes you're running on a SUN4 machine. If not, see below for making a different fields.o.
Also, the fields library is part of the libfdr library, which also includes doubly linked lists and red-black trees. I recommend you port that and use all three.
#define MAXLEN 1001
#define MAXFIELDS 1000
typedef struct inputstruct {
char *name; /* File name */
FILE *f; /* File descriptor */
int line; /* Line number */
char text1[MAXLEN]; /* The line */
char text2[MAXLEN]; /* Working -- contains fields */
int NF; /* Number of fields */
char *fields[MAXFIELDS]; /* Pointers to fields */
int file; /* 1 for file, 0 for popen */
*IS;
extern IS new_inputstruct(/* FILENAME -- NULL for stdin */);
extern IS pipe_inputstruct(/* COMMAND -- NULL for stdin */);
extern int get_line(/* IS */); /* returns NF, or -1 on EOF. Does not
close the file */
extern void jettison_inputstruct(/* IS */); /* frees the IS and fcloses
the file */
To use fields.o, you must include fields.h in your C program,
and compile it with fields.o. To read a file with fields.o
you call new_inputstruct() on that file. New_inputstruct()
takes a file name as its argument (NULL for standard input), and
returns an IS as a result. If it cannot open the file, it
will return NULL.
Once you have an IS, you call get_line() on it to read a line. Get_line() changes the state of the IS to reflect the reading of the line. Specifically:
These procedures are very convenient for processing input files. For example, the following program (in printwords.c) prints out every word of an input file prepended with its line number.
#include < stdio.h >
#include "fields.h"
main(argc, argv)
int argc;
char **argv;
{
IS is;
int i;
if (argc != 2) {
fprintf(stderr, "usage: printwords filename\n");
exit(1);
}
is = new_inputstruct(argv[1]);
if (is == NULL) {
perror(argv[1]);
exit(1);
}
while(get_line(is) >= 0) {
for (i = 0; i < is->NF; i++) {
printf("%d: %s\n", is->line, is->fields[i]);
}
}
jettison_inputstruct(is);
exit(0);
}
So, for example, if the file
rex.in
contains the following three
lines:
June: Hi ... I missed you! Rex: Same here! You're all I could think about! June: I was?Then running printwords on rex.in results in the following output:
UNIX> printwords rex.in 1: June: 1: Hi 1: ... 1: I 1: missed 1: you! 2: Rex: 2: Same 2: here! 2: You're 2: all 2: I 2: could 2: think 2: about! 3: June: 3: I 3: was? UNIX>One important thing to note about fields.o is that only new_inputstruct() calls malloc(). Get_line() simply fills in the fields of the IS structure --- it does not perform memory allocation. Therefore, suppose you wanted to print out the first word on the second-to-last line. The following program (badword.c) would not work:
#include < stdio.h >
#include "fields.h"
main(argc, argv)
int argc;
char **argv;
{
IS is;
int i;
char *penultimate_word;
char *last_word;
if (argc != 2) {
fprintf(stderr, "usage: badword filename\n");
exit(1);
}
is = new_inputstruct(argv[1]);
if (is == NULL) {
perror(argv[1]);
exit(1);
}
penultimate_word = NULL;
last_word = NULL;
while(get_line(is) >= 0) {
penultimate_word = last_word;
if (is->NF > 0) {
last_word = is->fields[0];
} else {
last_word = NULL;
}
}
if (penultimate_word != NULL) printf("%s\n", penultimate_word);
jettison_inputstruct(is);
exit(0);
}
Why? Look at what happens when you execute it on rex.in:
UNIX> badword rex.in June: UNIX>It prints ``June:'' instead of ``Rex:'' because get_line() does not allocate any new memory. Both penultimate_word and last_word end up pointing to the same thing. Make sure you understand this example, because you can get yourself into a mess of trouble otherwise. The correct version of the program is in goodword.c: (note that this is a very inefficient program because of all the strdup() and free() calls. You could do better if you wanted to).
Field.o assumes that all input lines are less than 1000 characters.