fgets maximum size read

2019-05-28 11:32发布

问题:

Using fgets to input a string, I have doubts related to length of string read.

For example, consider the following program.

char str[50];
int i;
int len;
printf("Enter name:\n");
fgets(str,11,stdin);
len = strlen(str);
printf("len :  %d\n",len);
  1. If I enter 123456789, strlen gives 10.

  2. If I enter 1234567890, strlen given is 10 again ??

I think strlen is considering newline also for string length. Am I correct? (I understand fgets using newline as part of string)

What's wrong with (2) where I enter exactly 10 characters, Here string length should be 11 right? 10 + 1 (for newline) = 11

回答1:

fgets reads at most 1 fewer characters than the length argument given, and does retain the newline as part of the input - so long as the newline is part of the first (length - 1) characters.

So in your first case, assuming that 123456789 is followed by a newline, fgets has read 9 characters including the newline, yielding a string length of 10; in your second case, fgets will stop after reading the 10 characters 1234567890, yielding a string length of 10.



回答2:

Here is an example:

#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;
}

Sample output, with "MAX_DIGITS" and "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.

You'll notice:

  1. The return buffer retains the "\n" as long as the #/digits are < MAX_DIGITS.

  2. The "\n" is REMOVED when #/digits >= MAX_DIGITS.

  3. Your buffer must accomodate MAX_DIGITS+1



回答3:

Actually fgets requires a size specification (in your case 11) account for the \0 at the end of a string. From the fgets man page:

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.

So we know that reading stops at \n, when you enter 123456789\n. However when you enter 1234567890\n, fgets() processes the input but it only takes the 10 characters and ignores everything else afterwards.

Any extra input of your string and your string will at size-1 of fget() with last character as \0 so the output remains the same.



标签: c string fgets