#c #iostream #standards
#c #iostream #стандарты
Вопрос:
В стандарте C (раздел 27.6.1.3 24) для функции istream ignore()
в библиотеке IOStreams это подразумевает, что если вы укажете аргумент для ‘n’ из numeric_limits::max()
, он будет продолжать игнорировать символы вечно, пока не будет найден разделитель, даже намного превышающий фактическое максимальное значение для streamsize (т. Е. аргумент ‘n’ интерпретируется как бесконечный).
Для реализации gcc это действительно похоже на то, как ignore()
реализовано, но мне все еще неясно, зависит ли это от конкретной реализации или предписано стандартом. Может ли кто-нибудь, кто хорошо это знает, подтвердить, что это гарантировано стандартной библиотекой iostreams?
Комментарии:
1. вы имеете в виду
std::numeric_limits
, конечно?2. Что вы делаете, чтобы предоставить numeric_limits::max() количество символов для объекта istream?
3. какой объект istream вы используете и как вы проверяете это условие? Это не может быть cin, потому что для ввода такого количества символов требуется примерно более 20 часов. Меня больше интересует ваш способ тестирования, а не фактический ответ 🙂
4. @Eric: Ну, если вы компилируете на 32-разрядной машине (без включенной LFS), то выполнение этого для файла размером более 4 ГБ должно достичь предела.
Ответ №1:
Стандарт гласит, что numeric_limits<streamsize>::max()
это специальное значение, которое не влияет на количество пропущенных символов.
Эффекты: Ведет себя как неформатированная функция ввода (как описано в 27.7.2.3, параграф 1). После создания объекта sentry извлекает символы и отбрасывает их. Символы извлекаются до тех пор, пока не произойдет любое из следующих событий:
— еслиn != numeric_limits<streamsize>::max()
(18.3.2) извлекается n символов
— во входной последовательности возникает конец файла (в этом случае функция вызывает setstate(eofbit), что может вызвать ios_base::сбой (27.5.5.4));
— признаки::eq_int_type(признаки::to_int_type(c), delim) для следующего доступного входного символа c (в какой случай c извлекается).
Комментарии:
1. Да, это именно то, о чем я говорю — это указывает, что произойдет, если n != numeric_limits::max(), но не указывает, что произойдет, если n равно numeric_limits::max() ; отсюда вопрос.
2. Моя интерпретация этого заключается в том, что если n == numeric_limits::max(), символы не учитываются в соответствии с ограничением. Мы просто ищем разделитель или конец файла. С другой стороны, streamsize будет одним из самых больших целых чисел, которые у нас есть, поэтому в любом случае было бы трудно достичь этого значения.
3. Я считаю, что это следует читать следующим образом: (1) есть три условия, которые могут завершить цикл. (2) Одним из них является то, что n!= max и n символов были извлечены. (3) Одним из них является EOF. (4) Одним из них является совпадение разделителя. Если n == max, то (2) никогда не может произойти, поэтому существует только 2 возможных условия завершения. Во всех случаях, когда в стандарте указано «if X, Y», это означает, что Y применяется только тогда, когда X равно true. Если X равно false, Y не имеет значения.
4. Альтернативное, педантично логичное прочтение заключается в том, что при n == max первое условие «если X, то Y» является абсолютно истинным, поскольку X равно false, и, следовательно, извлечение немедленно прекращается. Это не то, что означает стандарт, когда он формулирует вещи таким образом. В любом случае, нет разумного прочтения этого абзаца, в котором говорится, что «извлечено n символов» является условием завершения, когда n == max. Поэтому мы должны заключить, что это не так.
Ответ №2:
Согласно здесь:
istreamamp; istream::ignore ( streamsize n = 1, int delim = EOF );
Извлекать и отбрасывать символы
Извлекает символы из входной последовательности и отбрасывает их.
Извлечение заканчивается, когда n символов были извлечены и отброшены или когда найден разделитель символов, в зависимости от того, что наступит раньше. В последнем случае также извлекается сам символ ограничения.
В вашем случае, когда достигнуто количество символов numeric_limits::max(), выполняется первое условие.
[Для каждого пользователя]
Однако, согласно спецификации, приведенный выше случай применяется только тогда, когда n не равно numeric_limits<streamsize>::max()
.
Комментарии:
1. Нет, в стандарте явно сказано, что это только в том случае, когда n != numeric_limits()::max. (Взгляните на выдержку из ответа Bo.)
2. Никогда ни за что не верьте cplusplus на слово. Это чрезмерно упрощает, потому что он считает, что лучше иметь некоторое описание того, что делает функция, чем не понимать точного описания того, что делает функция.
3. @Steve, спасибо за твой совет. Обращение к спецификации — это последний способ, которым мы можем решить такие проблемы.