[Courses] [C] Beginner's Lesson: How do I...?

Akkana akkana at shallowsky.com
Fri Dec 13 22:11:06 EST 2002


KWMelvin writes:
> My first program created a sequential text file.  My next program
> will read the sequential text file that was created, record by
> record, formatting the output of each field, and sending that to stdout.
> 
> This may not have ANY use in the real world!  I certainly haven't been

Oh, it certainly has uses in the real world!  Well, perhaps not sending
it to stdout; but certainly parsing tab delimited fields (or comma
delimited, or comparable formats) read from a file a line at a time
is a very common thing for a program to do.

strtok() is a reasonable way to go about this, though one might easily
be put off by the fact that the man page for it says:

BUGS
       Never use these functions.

:-)  (The reason for that appears to be that (1) it modifies its
argument, which means that you have to be careful what you pass in
to it, and (2) it's not reentrant, which means that you'd better not
use it in a multi-threaded program.  Neither of those is likely to
apply in your case, but it does suggest you might not want to get
too dependant on strtok.)

Myself, I'd probably tend to just write the parsing myself, if it's
something as simple as looking for a tab.  Something like this:

/* Copy from the beginning of line to the first ocurrence of outputBuf.
 * Returns the location of the delimiter if it saw it, else 0.
 */
char* CopyNextWord(char* line, char delim, char* outputBuf, int maxchars)
{
  int i = 0;
  while (line[i] != '\0' && i < maxchars-1 && line[i] != delim)
    ++i;

  /* Now we've either hit the end of line, we've hit maxchars,
   * or we've seen the delimiter.
   * In any of these cases, we want to copy what we have, and return.
   */
  strncpy(outputBuf, line, i);

  /* and make sure it's null terminated */
  outputBuf[i] = '\0';

  if (line[i] == '\0' || i >= maxchars-1)
    return 0;
  return line + i + 1;
}

Then you could call that four times, each time searching forward to
the next occurrence of the tab using the return value of CopyNextWord:

for (j=0; j<4 && line; ++j)
{
  line = CopyNextWord(line, '\t', my4OutputArrays[j], 20);
}

	...Akkana



More information about the Courses mailing list