Newsgroups: comp.lang.c,de.comp.lang.c,fj.lang.c,maus.lang.c,umn.cs.lang.c
Path: galaxy.trc.rwcp.or.jp!jaist-news!cs.titech!nirvana.cs.titech!wnoc-tyo-news!news.u-tokyo.ac.jp!sinetnews!daffy!uwvax!uwm.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!EU.net!sun4nl!baby!jos
From: jos@and.nl (Jos Horsmeier)
Subject: Re: Help with easy questions please
Message-ID: <CMJwuq.51E@and.nl>
Organization: AND Software B.V., Rotterdam
References: <2lq76fINNa90@bhars12c.bnr.co.uk>
Date: Sat, 12 Mar 1994 12:18:25 GMT
Lines: 93
Xref: galaxy.trc.rwcp.or.jp fj.lang.c:1424
X-originally-archived-at: http://galaxy.rwcp.or.jp/text/cgi-bin/newsarticle2?ng=fj.lang.c&nb=1424&hd=a
X-reformat-date: Mon, 18 Oct 2004 15:18:22 +0900
X-reformat-comment: Tabs were expanded into 4 column tabstops by the Galaxy's archiver. See http://katsu.watanabe.name/ancientfj/galaxy-format.html for more info.

In article <2lq76fINNa90@bhars12c.bnr.co.uk> ace@bnr.co.uk (A D C Elly) writes:

|I want to be able to open and read a file one line at a time.  Once I've
|read that first line into some structure or in some way I have to be able
|to process each line.  Each line consists of words or numbers separated
|by a space.  Depending on what word starts a line a different set of
|actions has to be carried out.
|
|For instance, I open the input file and then read in a line from it.  Then 
|I check the first word (since I know that each word on the line is separated
|by a space I 'read' the characters until I come to a space).  If the first
|word is, for instance, SEND, I know that there are going to be two other
|words following this word which I have to process.  So, how do I read in
|each line, one at a time, from the input file.  And into what structure do
|I read it into?  An array of 80 chars?
|
|Then how do I process the line.  I had thought that I could use a case
|statement or a series of IF .. ELSE statements.  But with there being 14
|different possible 'first words' isn't that too many IF .. ELSEs or CASE
|statements?

You could use a <command, action> table. Something like this:

typedef struct {
char *command;
void (*action)(char *);
} command_t;

Initialize a table with fourteen (plus one) tuples:

void first_func(char*);
void second_func(char*);
...
void fourteenth_func(char*);
void error_func(char*);

command[] = {
{ "first", first_func      },
{ "second", second_func     },
{ "fourteenth"  , fourteenth_func },
{ "", error_func      },
};

where first_func() ... fourteenth_func() implement the actions to
be taken when the "first" ... "fourteenth" command has been read.
Note the last sentinel value (read on ...)

The following function reads a line from a file, finds the corresponding
function in the table defined above and dispatches it. The function
returns a non zero value iff a line could be read from a file:

int dispatch(FILE *fd) {

char line[BIGENOUGH];
char *args;
int  i;

if (fgets(line, sizeof(line), f)) {/* read a line */

strtok(line, " \t");/* skip command */
args= strtok(NULL, " \t);/* get args */

for (i= 0; command[i].command[o]; i++)
if (!strcmp(command, command[i].command))
break;

command[i].action(args);
return 1;
}
return 0;

}

The error_func could be as simple as:

void error_func(char *args) {
fprintf(stderr, "unknown command\n");
}

After opening the file, all commands could be executed in a
simple while loop:

while (dispatch(file))
;

I hope this helps you out,

kind regards,

Jos aka jos@and.nl
----------------------------------------------------------------------------
Flee,Flee,Flah,Flow,Webster,Ooh,Ooh,Webster,Eenymini,Sayemini,Ooh,Ooh,
Eenymini,Tessamini,Ooh,it's a bidde olde body,poopoo,petite,tube,tsss.
