Reputation: 11
fseek(fPtr, 0, SEEK_END);
fflush(stdin);
printf("\n\t\t\t ENTERID : ");
fgets(user.id, ID_SIZE, stdin);
fflush(stdin);
printf("tENTER FIRST NAME: ");
fgets(user.fname, MAX_FNAME_SIZE, stdin); //automatic added newline
printf("ENTER LAST NAME: ");
fgets(user.lname, MAX_LNAME_SIZE, stdin); //automatic added newline
I was using fgets() for reading the input of the string and store into the text file using the fwrite. But why does fgets() automatically enter a newline for each input of string.
Upvotes: 1
Views: 675
Reputation: 23218
"...but gets() no issue about newline"
Note, that although your observation about gets()
being preferable in this case over fgets()
for handling newline, the unfavorable behaviors that come with gets() make it dangerous to use, with the result that "it was officially removed by the 2011 standard." (credit) Even without the \n
mitigations mentioned below, fgets() is highly preferred over gets()
.
"fgets() goes newline when storing string..." and "...why does fgets() automatically enter a newline for each input of string"
fgets()
does not enter the newline upon reading the line, rather if one exists, the newline is picked up as part of the line when fgets()
called. For example in this case, when using stdin
as the input method, the user clicks the <return>
to finish inputting text. Upon hitting the <return>
key, a \n
is entered just like any other character, and becomes the last character entered. When the line is read using fgets()
, if the \n
is seen before any of its other stop reading criteria, fgets()
stops reading, and stores all characters, including \n
, terminates line with \0
and stores into the buffer. (If sizeof(buffer) - 1
or EOF is seen first, fgets()
will never see the newline.)
To easily eliminate the \n
, (or other typical unwanted line endings), use the following single line statements after each of your calls to fgets():
fgets(user.id, ID_SIZE, stdin);
user.id[strcspn(user.id, "\n")] = 0;
//fflush(stdin);//UB, should not be called
...
fgets(user.fname, MAX_FNAME_SIZE, stdin);
user.fname[strcspn(user.fname, "\n")] = 0;
...
fgets(user.lname, MAX_LNAME_SIZE, stdin);
user.lname[strcspn(user.lname, "\n")] = 0;
...
This technique works for truncating any string by searching for the unwanted char
, whether it be "\n"
, "\n\r"
, "\r\n"
, etc. When using more than one search character, eg "\r\n"
, it searches until it reaches either the \r
or the \n
and terminates at that position.
"This [method] handles the rare buffer than begins with '\0'
, something that causes grief for the buffer[strlen(buffer) - 1] = '\0';
[method]." (@Chux - comment section of link below.)
Upvotes: 1
Reputation: 134336
Quoting from the 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, after providing the input from the terminal, you press the ENTER key which adds a newline to the input buffer. That same newline is scanned and stored in the destination provided to fgets()
.
If you want to remove the trailing newline, use the solution mentioned in the answer: Removing trailing newline character from fgets() input
That said, read:
Upvotes: 0