Complete.Org: Mailing Lists: Archives: discussion: March 2000:
[aclug-L] Re: Weekly C quiz
Home

[aclug-L] Re: Weekly C quiz

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: discussion@xxxxxxxxx
Subject: [aclug-L] Re: Weekly C quiz
From: Tom Hull <thull@xxxxxxxxxxx>
Date: Sat, 11 Mar 2000 21:10:38 -0600
Reply-to: discussion@xxxxxxxxx

John Reinke wrote:
> 
> Okay, here's the one line answer:
> 
> while (fscanf(in_file, "%*[\n]%200[^\n]%*[^\n]", buffer) && !feof(in_file))

This looks like it will fail if the first character in in_file is not \n.
It also looks like it will fail a last line which does not end in newline,
since EOF will have been encountered in filling up buffer or discarding
the overflow.

The feature of ignoring blank lines seems to be an artifact of the code
rather than an original requirement. I do think it is appropriate to view
the consistent stripping of newlines as a requirement.

I tried writing a test program using the above fscanf(), and it failed as
I expected. Moreover, I couldn't figure out any way to fix it. (Moving the
initial "%*[\n]" to the end seemed like the first move, which indeed got
me the first line, and sometimes a second line.) Which just goes to remind
me that in >20 years of C programming, I've never written a program which
actually used fscanf(), for the basic reason that I've never understood
how it re-synchs on erroneous input. (I've always suspected that it don't.)

My original suggestion was just to write your own loop. Something like
this will do:

    FILE *in_file;
    char buff[200], *p, *ep = buff + sizeof buff - 1;
    int c;

    for ( ; ; ) {
        p = buff;
        while ((c = getc(in)) != EOF && c != '\n') {
            if (p < ep) *p++ = c;
        }
        *p = 0;
        if (c != EOF || p > buff) {
            /* do something with buff here */
        }
        else
            break;
    }

> There is no way that I know of to specify a field width in a fscanf without
> hard-coding the actual value, and MAX_BUF can't be used within a string, so
> note that I put the value 200 in the format string.
> 
> In the case that the entire line DOES fit in the buffer, you won't have to
> worry about stripping the newline character from the end like, as in the
> original code.
> 
> This version will also ignore blank lines.
> 
> What's the prize?  :-)
> 
> BTW, you've got to stop asking these questions. They're so much fun, I
> never get anything else done.  ;-)
> 
> John
> 
> >Here's the next installment of Larry's Weekly C Quiz. This week we're
> >looking at buffer overruns. Here's some code:
> >
> >#define MAX_BUF 201
> >...
> >char buffer[MAX_BUF];
> >FILE *file_in;
> >...
> >while (fgets(buffer, sizeof(buffer), file_in) != NULL) {
> >....
> >}
> >
> >
> >If fgets returns a line from file_in's file bigger than MAX_BUF, buffer
> >is full at the maximun size, the rest not going into buffer: good. But
> >then the next fgets seems to fill buffer with the leftover from the
> >input file's last line. How can I "flush" fgets so a longer line's
> >leftover doesn't show up in the next fgets?
> >
> >Larry
> 
> -- This is the discussion@xxxxxxxxx list.  To unsubscribe,
> visit http://tmp2.complete.org/cgi-bin/listargate-aclug.cgi

-- 
/*
 *  Tom Hull * thull@xxxxxxxxxxx * http://www.ocston.org/~thull/
 */

-- This is the discussion@xxxxxxxxx list.  To unsubscribe,
visit http://tmp2.complete.org/cgi-bin/listargate-aclug.cgi


[Prev in Thread] Current Thread [Next in Thread]