This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

scanf conflict with conclusions of WG 14 Defect Report 017 Question 29

Sigh... One more attempt to convince Ulrich Drepper that scanf is broken.

/* glibc scanf violates the behavior specified in Defect Report #022 Question 29.


  Question 29
  Conversion failure and longest matches
  Consider 1.2e+4 with field width of 5. Is it input item 1.2e+ that gives a
  conversion failure? What is the ordering between building input items and
  converting them? Do they run in parallel, or sequential?
  Refer to subclause The fscanf function, page 135, lines 31-33
  concerning the longest matching sequence, and subclause, page 137,
  lines 15-16 concerning a conflicting input character.
  For 1.2e-x, is 1.2 or 1.2e- read?
  The above questions all come about because of page 137, line 15: ``If
  conversion terminates ...'' In this context the use of the word
  ``conversion'' could be referring to the process of turning a sequence
  of characters into numeric form. I believe what was intended was ``If
  a conversion specifier terminates ...''

  The relevant citations are subclause, page 137, lines 15-16:
    If conversion terminates on a conflicting input character, the offending
    input character is left unread in the input stream.  
  and subclause, page 135, lines 31-33:
    An input item is defined as the longest matching sequence of input
	characters, unless that exceeds a specified field width, in which case
	it is the initial subsequence of that length in the sequence.
  and subclause, page 135, lines 38-40:
    If the input item is not a matching sequence, the execution of the
	directive fails: this condition is a matching failure.
  The ``conversion'' in the first quoted passage is the process of both
  forming an input item and converting it as specified by the conversion
  About your example: If the characters available for input are `` 1.2e+4''
  and input is performed using a ``%5e,'' then the input item is ``1.2e+''
  as defined by the second passage quoted above. That input item is not a
  matching sequence, but only an initial subsequence that fails to be a
  matching sequence in its own right. Under the rules of the third quoted
  passage, this is a matching failure.
  Note that in this case, no characters were pushed back onto the input stream.
  There was no ``conflicting input character'' that terminated the field, and
  so the first quoted passage does not apply.
  See the Correction made in response to Defect Report #022, Question 1,
  for additional clarification. 


#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main(void)
	float x;
	FILE *fp;
	int n;
	int c;

	if (!(fp = fmemopen("1.2e+4", 6, "r"))) {
		printf("fmemopen failed!\n");
		return EXIT_FAILURE;

	n = fscanf(fp, "%5g", &x);
	printf("fscanf returned %d, ferror=%d, feof=%d, and the next fgetc returned ",
		   n, ferror(fp), feof(fp));
	if ((c = fgetc(fp)) < 0) {
		return EXIT_FAILURE;
	if (isprint(c)) {
		printf("'%c'\n", c);
	} else {
		printf("'\\x%.2x'\n", c);

	if (n == 0) {
	} else {
		printf("Error: By the response to Defect Report #022 Question 29,\n"
			   "  scanf should have returned 0 due to a matching failure!\n");
		return EXIT_FAILURE;

	if (c != '4') {
		printf("Error: By the response to Defect Report #022 Question 29,\n"
			   "  the fgetc following fscanf should have returned '4'!\n");
		return EXIT_FAILURE;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]