2011-07-14 2 views
6

Спецификация для strtol концептуально делит входную строку на «начальные пробелы», «последовательность субъектов» и «конечную строку» и определяет «последовательность субъектов» как:Сложный язык в спецификации strtol и др.

самая длинная начальная подпоследовательность входной строки, начиная с первого символа небелого пробела, который имеет ожидаемую форму. Тематическая последовательность не должна содержать символов, если входная строка пуста или состоит полностью из символов пробела или если первый символ небелого пробела отличается от знака или допустимой буквы или цифры.

В свое время я думал, что «длинная начальная подпоследовательности» бизнес был сродни путь scanf работ, где "[email protected]" будет сканировать в "0x", отказавшего матч, а затем "@" в следующей непрочитанной характер. Однако после некоторого обсуждения я в основном убежден, что strtol обрабатывает самую длинную начальную подпоследовательность, которая имеет ожидаемую форму, а не самую длинную начальную строку, которая является начальной подпоследовательностью некоторой возможной строки ожидаемой формы.

Что еще смущает меня этот язык в спецификации:

Если испытуемый последовательность пуста или не имеет ожидаемую форму, не выполняется преобразование; значение str хранится в объекте, на который указывает endptr, при условии, что endptr не является нулевым указателем.

Если мы принимаем то, что, кажется, правильное определение «испытуемым последовательности», не существует такого понятия, как непустой сюжетную последовательность, которая не имеет ожидаемую форму, и вместо того, чтобы (во избежание дублирования и путаницы) текст следует просто читать:

Если последовательность предметов пуста, преобразование не выполняется; значение str хранится в объекте, на который указывает endptr, при условии, что endptr не является нулевым указателем.

Может ли кто-нибудь прояснить эти вопросы для меня? Возможно, полезной была бы ссылка на прошлые обсуждения или любые соответствующие отчеты о дефектах.

+1

И простой нормативный пример мог бы очистить все до нуля ... –

+1

Действительно. У меня такое чувство, что комитет действительно пытался избежать явного страха открыть аргумент о том, как он должен себя вести ... –

ответ

1

POSIX spec for strtol кажется более ясным:

Эти функции должны преобразовать начальная часть строки, на которую указывает ул к типу длинного и длинного длинного представления, соответственно. Во-первых, они разлагаются входную строку на три части:

  1. Начальная, возможно, пустой, последовательность пробельных символов (как определено isspace())

  2. Субъект последовательность интерпретируется как целое число представленный в некотором радиусе, определяемом значением базы

  3. Окончательная строка одного или нескольких непризнанных символов, включая завершающий символ NUL входной строки.

Затем они попытаются преобразовать последовательность объектов в целое и вернуть результат.

Но, конечно, это не является нормативным и «нарушает стандарт ISO C».

+0

Я все равно читал версию спецификации POSIX. :-) –

+0

Какая ревизия POSIX? Может быть, они разъяснили формулировку? – Nemo

+0

2008, тот же самый, с которым вы связались. –

3

Я думаю, что язык C99 совершенно ясно:

Субъект последовательность определяется как самый длинный начальный подпоследовательности входной строки, начиная с первого небелого-символа пробела, , который из ожидаемая форма.

"[email protected]", "[email protected]" не имеет ожидаемого вида; "0x" не имеет ожидаемой формы; поэтому "0" - самая длинная начальная подпоследовательность, которая имеет ожидаемую форму.

Я согласен, что это означает, что вы не можете иметь непустое предмет последовательности, которая не является ожидаемой формы - если вы не интерпретировать следующим образом:

В другом чем "C" местности, дополнительные locale- конкретный субъект формы последовательности могут быть приняты.

... так как позволяет языку определять другие возможные формы, которые могут иметь субъектная последовательность, которые, тем не менее, не относятся к «ожидаемой форме».

Формулировка в заключительном параграфе, по-видимому, является просто «поясом и скобами».

+0

Мне интересно, как вы думаете можно было бы ласкать вокруг требования с предложением locale .. :-) –

2

Это может быть проще понять, если вы начали в §7.20.1.4 (The strtol, strtoll, strtoul и strtoull функции) ¶2 стандарта C99, вместо ¶4:

¶2 Функции strtol, strtoll, strtoul и strtoull преобразуют начальную часть строки строки, на которую указывает nptr, long long int, unsigned long int и беззнаковое длинное длинное представление, соответственно. Во-первых, они разлагают входную строку на три части: начальную, возможно пустую, последовательность символов 0 пробела (как определено функцией isspace), последовательность субъекта , напоминающую целое число, представленное в некотором радике, определяемое значением base и конечная строка одного или нескольких нераспознанных символов, включая нулевой символ входной строки. Затем они пытаются преобразовать последовательность объектов в целое число и возвращать результат.

¶3 Если значение базы равно нулю, ожидаемая форма предметной последовательности является то, что из целой константы, как описано в 6.4.4.1, необязательно предшествует знак плюс или минус, но не включая целое число суффикс. Если значение базы составляет от 2 до 36 (включительно), ожидаемая форма субъектной последовательности представляет собой последовательность букв и цифр, представляющих целое число с основанием, обозначенным базой, необязательно предшествующим знаку плюс или минус, но не включая целочисленный суффикс. Буквы от (или A) до z (или Z) равны , приписываются значения от 10 до 35; разрешены только буквы и цифры, значения атрибутов которых меньше . Если значение базы равно 16, символы 0x или 0X могут необязательно предшествуют последовательности букв и цифр, следуя знаку, если он присутствует.

¶4 субъекта последовательности определяется как самые длинными начальные подпоследовательности входной строки, ...

В частности, ¶3 разъясняет, что субъект последовательность.

1

Я полностью согласен с вашей оценкой: по определению все непустые последовательности подлежат ожидаемой форме, поэтому формулировка стандарта сомнительна.

В случае функций с плавающей точкой преобразования, есть еще одна ошибка (С99: раздел ТС3 7.20.1.3, § 3):

[...] Субъект последовательность определяется как самый длинный начальное подпоследовательность входной строки, начиная с первого символа небелого пробела, который имеет ожидаемую форму. Тема последовательность не содержит символов, если входная строка не соответствует ожидаемой форме .

Это означает, что вся входная строка должна быть ожидаемой форме, разгромив назначение параметра endptr. Можно утверждать, что ожидаемая форма для входной строки отличается от ожидаемой формы для данной последовательности, но она все еще довольно запутанна.

Вы также правильно, что семантика strto*() и *scanf() семейства функций различна: Если оба матча, они всегда договорятся о стоимости и потребляют одинаковое количество символов (и любые LibC реализации, где они не есть сломанной, в том числе newlib и glibc в прошлый раз, когда я проверил), но *scanf() дополнительно не соответствует случаям, когда требуется отменить более одного символа, как в ваших примерах "[email protected]" и "1.0e+".

Смежные вопросы