On 12/10/25 03:07, Anders Magnusson wrote:
Den 2025-12-09 kl. 20:22, skrev Roland Illig:
Am 09.12.2025 um 09:27 schrieb Anders Magnusson:
Morning,
Den 2025-12-09 kl. 03:49, skrev Robert Elz:
Date: Mon, 8 Dec 2025 20:45:00 +0100
From: Anders Magnusson<[email protected]>
Message-ID:<[email protected]>
| I just stumbled over something which may be a bug in scanf()...?
| This example is in C99 7.19.6.2 clause 20.
Yes, but nowhere there does it say what the result should be in the
case that you give, and I think you're arriving at an incorrect
conclusion.
Sorry, but I think that is very clear? The input scanning should stop
whenever something unwanted is read.
And as you noticed in the followup mail; this was an example from the
standard which was what I was referring to :-)
Also, as you note it should accept whatever strtod() do, _but_: C99 note
242 (C23 note 348) says:
"fscanf pushes back at most one input character onto the input stream.
Therefore, some sequences
that are acceptable to strtod, strtol, etc., are unacceptable to
fscanf.".
which is what should happen here (and the reason "100ergs" should fail
for %f in *scanf()).
When reading the 'r' the scanning for %f fails and it returns. As the
standard says...?
That's exactly the reasoning I had in mind. I wonder though why fscanf
is _required_ to reject this sequence, instead of allowing an
implementation with a larger pushback buffer to accept this string, thus
making this decision a quality-of-implementation issue. The C99
rationale doesn't mention this particular possibility.
The problem here is that it should be deterministic how the input will
be parsed and not vary depending on which stdio implementation there is.
The BSD stdio package gives this result:
count=3 quant=100.000000 units=ergs item=energy
Glibc gives this: (which also the original stdio package on 2BSD does)
count=3 quant=100.000000 units=rgs item=energy
But the C standard says that it should return count=0 which neither of
them does.
It would be interesting to know how some other (legacy) OSes parses,
like Solaris? Any takers available? :-)
Code snippet below:
#include <stdio.h>
main()
{
int count; float quant; char units[21], item[21];
count = sscanf("100ergs of energy\n",
"%f%20s of %20s", &quant, units, item);
printf("count=%d quant=%f units=%s item=%s\n",
count, quant, units, item);
}
$ uname -a
SunOS aurora 5.11 illumos-c2cbc6b847 i86pc i386 i86pc
$ cat test.c
#include <stdio.h>
main()
{
int count; float quant; char units[21], item[21];
count = sscanf("100ergs of energy\n",
"%f%20s of %20s", &quant, units, item);
printf("count=%d quant=%f units=%s item=%s\n",
count, quant, units, item);
}
$ cc -o test test.c
test.c:3:1: warning: return type defaults to 'int' [-Wimplicit-int]
3 | main()
| ^~~~
$ ./test
count=0 quant=-0.000000 units=LG item=P
$