fgets максимальный размер для чтения

Используя fgets для ввода строки, у меня есть сомнения, связанные с длиной прочитанной строки.

Например, рассмотрим следующую программу.

char str[50];
int i;
int len;
printf("Enter name:\n");
fgets(str,11,stdin);
len = strlen(str);
printf("len :  %d\n",len);
  1. Если я ввожу 123456789, strlen дает 10.

  2. Если я введу 1234567890, strlen снова будет 10 ??

Я думаю, что strlen рассматривает новую строку также для длины строки. Я прав? (Я понимаю, что fgets использует новую строку как часть строки)

Что не так с (2), где я ввожу ровно 10 символов. Здесь длина строки должна быть 11, верно? 10 + 1 (для новой строки) = 11


person kumar    schedule 24.06.2012    source источник
comment
printf(длина: %d,длина); printf(str : %s,str); printf(привет);вернуть 0; } Добавление нескольких отпечатков помогает прояснить приведенные ниже ответы. Обратите внимание, как напечатан привет.   -  person kumar    schedule 20.11.2012


Ответы (3)


fgets считывает не более чем на 1 символ меньше, чем указанный аргумент длины, и сохраняет новую строку как часть ввода - до тех пор, пока новая строка является частью первого (длина - 1) символа.

Таким образом, в вашем первом случае, предполагая, что за 123456789 следует новая строка, fgets прочитал 9 символов, включая новую строку, что дало длину строки 10; во втором случае fgets остановится после чтения 10 символов 1234567890, что даст длину строки 10.

person pb2q    schedule 24.06.2012
comment
Небольшое исправление: он не сохранит новую строку, если #/characters ›= max length. Как показано в примере ниже. - person paulsm4; 25.06.2012
comment
@paulsm4 Я думаю, это уже ясно из моей первой строки: читает не более чем на 1 символ меньше, чем указанный аргумент длины. - person pb2q; 25.06.2012

Вот пример:

#include <stdio.h>
#include <string.h>

#define MAX_DIGITS 5

int
main ()
{
  char buf[80];
  char *s = NULL;
  printf ("\n>>Enter string, %d digits or less: ", MAX_DIGITS);
  s = fgets (buf, MAX_DIGITS+1, stdin);
  printf ("strlen(buf)=%d, buf=%s, strlen(s)=%d, s=%s\n",
    strlen(buf), buf, strlen(s), s);
  return 0;
}

Пример вывода с «MAX_DIGITS» и «MAX_DIGITS + 1»:

>>Enter string, 5 digits or less: 1
strlen(buf)=2, buf=1
, strlen(s)=2, s=1
.

>>Enter string, 5 digits or less: 12
strlen(buf)=3, buf=12
, strlen(s)=3, s=12
.

>>Enter string, 5 digits or less: 123
strlen(buf)=4, buf=123
, strlen(s)=4, s=123
.

>>Enter string, 5 digits or less: 1234
strlen(buf)=5, buf=1234
, strlen(s)=5, s=1234
.

>>Enter string, 5 digits or less: 12345
strlen(buf)=5, buf=12345, strlen(s)=5, s=12345.

>>Enter string, 5 digits or less: 123456
strlen(buf)=5, buf=12345, strlen(s)=5, s=12345.

Вы заметите:

  1. Буфер возврата сохраняет "\n" до тех пор, пока #/цифры равны ‹ MAX_DIGITS.

  2. "\n" УДАЛЯЕТСЯ, когда #/digits >= MAX_DIGITS.

  3. Ваш буфер должен вмещать MAX_DIGITS+1

person paulsm4    schedule 24.06.2012
comment
‹‹Ваш буфер должен вмещать MAX_DIGITS+1. Таким образом, в буфере должно быть достаточно места для хранения новой строки, что равно +1. Спасибо за вашу помощь. - person kumar; 25.06.2012
comment
@kumar Для сохранения новой строки должно быть + 2, так как fgets уже забирает один для хранения нулевого значения терминатора -> '\ 0'; То есть, если вы передадите ему 6, он прочитает максимум 5 вещей (4 цифры + CR или 5 цифр). Если вы передадите его 7, он будет читать 5 цифр плюс возврат каретки. - person Scooter; 22.08.2012

На самом деле fgets требуется учетная запись спецификации size (в вашем случае 11) для \0 в конце строки. На справочной странице fgets:

fgets() считывает не более одного символа меньше size из потока и сохраняет их в буфер, на который указывает s. Чтение останавливается после EOF или новой строки. Если читается новая строка, она сохраняется в буфере. Завершающий нулевой байт ('\0') сохраняется после последнего символа в буфере.

Итак, мы знаем, что чтение останавливается на \n, когда вы вводите 123456789\n. Однако, когда вы вводите 1234567890\n, fgets() обрабатывает ввод, но принимает только 10 символов и игнорирует все остальное после этого.

Любой дополнительный ввод вашей строки и вашей строки будет равен size-1 из fget() с последним символом как \0, поэтому вывод останется прежним.

person Siddharth    schedule 12.09.2017