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: John Reinke <jmreinke@xxxxxxxxx>
Date: Sun, 12 Mar 2000 21:23:01 -0600
Reply-to: discussion@xxxxxxxxx

Okay. I went back and looked at my code. What I had submitted previously, I
had in fact tested, but used an old executable. I forgot to recompile it
first. :-)

Here's the version that worked, unfortunately it's now a whopping two lines:

while (fscanf(in_file, "%19[^\n]%*[^\n]", buffer) && !feof(in_file))
{
    fscanf(in_file, "%*[\n]");
    ...
}

For anyone who wants to know, here's how it works:

The %[] is like a %s, only you specify the characters or character ranges
(ie. A-Z) you want in the brackets. It stops filling the string with the
first character that does not match. If you preceed the character(s) with a
^, it will only take characters that DON'T match. The * means it should
look for whatevery type is specified, and discard it. In the case where
there is a number after the percent sign, that is the maximum number of
character to read. You have to make sure buffer contains an additional byte
for the null terminator, however.

The return value for fscanf is the number of arguments successfully read,
not including the discarded values from * format strings. So, it should
normally be one for the fscanf with the string buffer. At least, that's
what it is supposed to do. I had to include the feof() call - even though
no value should be getting read by the fscanf after EOF is encountered - to
get the condition to fail.

I usually use fgets, but the original problem sounded like a case where a
format string could come in handy for compact (although not pretty) code,
so I went with fscanf.

Here's the program I used for testing, I just recompiled and tested it one
more time. It works.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    FILE *in_file = NULL;
    char buffer[20];

    if (argc != 2)
    {
        fprintf(stderr, "usage: %s filename\n", argv[0]);
        exit (1);
    }
    if (!(in_file = fopen(argv[1], "r")))
    {
        fprintf(stderr, "error opening %s\n", argv[1]);
        exit (1);
    }

    while (fscanf(in_file, "%19[^\n]%*[^\n]", buffer) && !feof(in_file))
    {
        fscanf(in_file, "%*[\n]");
        printf("%s\n", buffer);
    }

    fclose(in_file);
    return 0;
}


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

Tom wrote:
>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.
>...
>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.
>...
>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.)
>...



-- 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]