Что означает `scanf` для неполной экспоненциальной части?

Возьмем, например, rc = scanf("%f", &flt); с входом 42ex. Реализация scanf читала бы 42e, думая, что после этого он столкнется с цифрой или знаком и первым поймет, когда читает x, что это не получилось. Должна ли она в этот момент отбросить как x, так и e? Или он должен только нажать x.

Причина, по которой я спрашиваю, заключается в том, что GNU libc будет при последующем вызове gets return ex указывать, что они отбросили оба значения x и e, но стандарт говорит:

Элемент ввода считывается из потока, если спецификация не содержит n спецификатора. Элемент ввода определяется как самая длинная последовательность входных символов, которая не превышает заданную ширину поля и которая является или является предварительной последовательностью входных последовательностей [245]. Первый символ, если он есть, после ввода элемента остается непрочитанным, Если длина входного элемента равна нулю, выполнение директивы выходит из строя; это условие является совпадающим сбоем, если только конец файла, ошибка кодирования или ошибка чтения не допускают ввода из потока, и в этом случае это ошибка ввода.

Я интерпретирую это так, поскольку 42e является префиксом соответствующей входной последовательности (поскольку, например, 42e1 будет подходящей входной последовательностью), что должно означать, что она рассмотрит 42e как элемент ввода, который должен читайте, оставляя только x непрочитанным. Это также было бы более удобно реализовать, если поток поддерживает только однократное нажатие на символ.

Ответ 1

Ваша интерпретация стандарта верна. Там еще пример ниже в стандарте C, который говорит, что 100ergs of energy не должен соответствовать %f%20s of %20s, потому что 100e не соответствует %f.

Но большинство библиотек C, похоже, реализуют это по-другому, вероятно, из-за исторических причин. Я просто проверил библиотеку C на macOS и вел себя как glibc. соответствующая ошибка glibc была закрыта как WONTFIX со следующим объяснением от Ulrich Drepper:

Это глупость на стороне комитета ISO C, которая идет вразрез с существующими практика. Любое изменение может нарушить существующий код.