2017-02-23 42 views
0

У меня есть следующий фрагмент кода в одной из моих программ:Какой размер следует использовать для fgets?

char input[LINE_SIZE + 1]; /* +1 for '\0'. */ 

while(fgets(input, LINE_SIZE, stdin) != NULL) 
{ 
    /* Do stuff. */ 
} 

В вопросе, который с тех пор был удален, он указал мне, что мой код потенциально может быть ошибка. Я объявляю строки с обозначением «+ 1», чтобы сделать код более информативным и читаемым (гарантируя, что я не забываю учитывать терминатор NULL, потому что это было проблемой). Однако мне сказали, что fgets должен использовать тот же самый размер для своего второго параметра. Я видел здесь другие сообщения, которые выполняют те же действия, что и я.

Я не уверен. Неправильная ли практика не включать «+ 1» в параметр fgets?

+3

Плюс/минус 1 не требуется. Предложить 'fgets (input, sizeof input, stdin)', когда 'input' является массивом. – chux

+1

Зачем передавать значение, которое вы * знаете * отключено на 1? Сказав это, он отключен на 1 в безопасном направлении, поэтому создает небольшой фактический риск. –

+1

для 'char input [LINE_SIZE + 1];', 'LINE_SIZE' - максимальное количество символов (не считая терминатора), а' LINE_SIZE + 1' - фактический размер массива. Для 'fgets()', вы передаете размер массива ... он будет читать не более одного меньшего символа, чем это, и добавьте терминатор. – Dmitri

ответ

3
7.21.7.2 fgets функция

Сводка

              #include <stdio.h>
                 

Описание

        fgets функция читает максимум один меньше, чем количество символов, указанных n из потока, на который указывает stream в массив, на который указывает s. Никакие дополнительные символы не считываются после символа новой строки (который сохраняется) или после окончания файла. A нулевой символ записывается сразу после того, как последний символ считывается в массив. добавлена ​​

C 2011 Online Draft

Акцент.

Если вы укажете LINE_SIZE, то fgets будет читать в самыхLINE_SIZE - 1 символов в input и напишет 0 терминатора следующего последний входного символа. Обратите внимание, что fgets сохранит символ новой строки, если есть место.

+0

Это очень сильно объясняет вопрос. Спасибо. Мне придется изменить все вхождения 'fgets', используя' LINE_SIZE', на 'LINE_SIZE + 1'. – moosefoot

0

Я не могу комментировать (< 50 баллов), но:

если вы используете

char input[LINE_SIZE ]; 

while(fgets(input, LINE_SIZE, stdin) != NULL) 
{ 
    /* Do stuff. */ 
} 

fgets() не будет писать за пределами вашей входной [] буфера, однако, если вы на самом деле нужно LINE_SIZE символов захваченный, вы получите этот последний символ сам по себе в следующем вызове, чего вы не ожидаете.

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

char * input = malloc(50)  
fgets(input, sizeof input, stdin) 

читает 8 (LP64)