fgets maximum size read

2019-05-28 10:45发布

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

标签: c string fgets
3条回答
再贱就再见
2楼-- · 2019-05-28 11:47

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.

查看更多
Juvenile、少年°
3楼-- · 2019-05-28 11:49

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

查看更多
劳资没心,怎么记你
4楼-- · 2019-05-28 11:50

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.

查看更多
登录 后发表回答