简体   繁体   中英

Why fgets takes cursor to next line?

I have taken a string from the keyboard using the fgets() function. However, when I print the string using printf() , the cursor goes to a new line.

Below is the code.

#include<stdio.h>
int main()
{
    char name[25];

    printf("Enter your name: ");
    fgets(name, 24, stdin);
    printf("%s",name);

    return 0;
}

And below is the output.

-bash-4.1$ ./a.out
Enter your name: NJACK1 HERO
NJACK1 HERO 
-bash-4.1$

Why is the cursor going to the next line even though I have not added a \\n in the printf() ?

However, I have noticed that if I read a string using scanf() , and then print it using printf() (without using \\n ), the cursor does not go to next line.

Does fgets() append a \\n in the string ? If it does, will it append \\0 first then \\n , or \\n first and then \\0 ?

The reason printf is outputting a newline is that you have one in your string.

fgets is not "adding" a newline --- it is simply reading it from the input as well. Reading for fgets stops just after the newline (if any).

Excerpt from the manpage , emphasis mine:

The fgets() function reads at most one less than the number of characters specified by size from the given stream and stores them in the string str. Reading stops when a newline character is found, at end-of-file or error. The newline, if any, is retained. If any characters are read and there is no error, a `\\0' character is appended to end the string.

An easy way to check if there's a newline is to use the help of one of my favorite little-known functions --- strcspn() :

size_t newline_pos = strcspn(name, "\r\n");
if(name[newline_pos])
{
    /* we had a newline, so name is complete; do whatever you want here */
    //...

    /* if this is the only thing you do
       you do *not* need the `if` statement above (just this line) */
    name[newline_pos] = 0;
}
else
{
    /* `name` was truncated (the line was longer than 24 characters) */
}

Or, as an one-liner:

// WARNING: This means you have no way of knowing if the name was truncated!
name[strcspn(name, "\r\n")] = 0;

Because if there is a '\\n' in the read text it will be taken by fgets() , the following was extracted from the 1570 draft §7.21.7.2 ¶ 2

The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array.

I highlighted by making bold the part which says that the '\\n' is kept by fgets() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM