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);
If I enter 123456789
, strlen
gives 10.
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
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.
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:
The return buffer retains the "\n" as long as the #/digits are < MAX_DIGITS.
The "\n" is REMOVED when #/digits >= MAX_DIGITS.
Your buffer must accomodate MAX_DIGITS+1
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.