On 23.04.2012 15:33, John Reye wrote:
> Hello,
>
> The last character read from fgets(buf, sizeof(buf), inputstream) is:
> '\n'
> OR
> any character x, when no '\n' was encountered in sizeof(buf)-1
> consecutive chars, or when x is the last char of the inputstream
>
> ***How can one EFFICIENTLY determine if the last character is '\n'??
> "Efficiently" means: don't use strlen!!!
What makes you so sure that this is inefficient? I would believe that in
almost all cases the IO operation is the dominant part of the code, and
the strlen is almost surely irrelevant. If this is not the case for you,
could you provide a complete working example you benchmarked where
strlen() turned out to be the bottleneck?
> I only come up with the strlen method, which - to me - says that fgets
> has a bad design.
fgets() has a simple design that works in simple cases. For example, it
cannot extend the buffer it reads the string into, which is for really
robust programs a more severe problem than the inconvenience of not
returning an indicator whether the overflow happened. If you need
something more complex, it's simple to write a replacement.
> int main(int argc, char *argv[])
> {
> char buf[6];
> FILE *fp = stdin;
> while (fgets(buf, sizeof(buf), fp)) {
> printf((buf[strlen(buf)-1] == '\n') ? "Got a line which ends with
> newline: %s" : "no newline: %s", buf);
> }
This program does not look like as if it would profit from a more
streamlined library call. I/O time will likely be dominating here,
especially for a buffer that small.
> A well-designed fgets function should return the length of characters
> read, should it not??
No, a well-designed fgets would possibly allocate the buffer itself. But
whether this fits your needs - or not - is application dependent. Maybe
you don't have the luxury of dynamic memory in some cases? As already
said, it is a simple function.
> Please surprise me, that there is a way of efficiently determining the
> number of characters read. ;)
> I've thought of ftell, but I think that does not work with stdin.
This is surely not *more* efficient but *less* efficient as it requires
(at least sometimes) the interaction with the operating system,
especially with the I/O system. This is what tends to be slow, not
iterating over six characters. Estimating the overall number of
instructions an average CPU has to execute to compute the strlen of a
six character string, and to execute ftell, I would bet that the latter
is far less efficient than the former.
> Because right now, I think that fgets really seems useless.
No. The usefulness of a function depends on its application. That
fgets() is in the standard library shows at least that it was useful at
some point.
> Why is the standard C library so inefficient?
Is it?
> Do I really have to go about designing my own library? ;)
If you have special needs, you need to write special code. But actually,
I doubt that *this* specific problem here makes any difference at all.
Except if strings are very very long, and if so, then processing the
input as strings is probably not the right approach in first place.
So long,
Thomas