How to remove trailing newline character from fgets() input? [Answered]

Sample problem:

I am trying to get some data from the user and send it to another function in gcc. The code is something like this.

printf("Enter your Name: ");
if (!(fgets(Name, sizeof Name, stdin) != NULL)) {
    fprintf(stderr, "Error reading Name.\n");
    exit(1);
}

However, I find that it has a newline \n character in the end. So if I enter John it ends up sending John\n. How do I remove that \n and send a proper string.

How to remove trailing newline character from fgets() input? Answer #1:

Perhaps the simplest solution uses one of my favorite little-known functions, strcspn():

buffer[strcspn(buffer, "\n")] = 0;

If you want it to also handle '\r' (say, if the stream is binary):

buffer[strcspn(buffer, "\r\n")] = 0; // works for LF, CR, CRLF, LFCR, ...

The function counts the number of characters until it hits a '\r' or a '\n' (in other words, it finds the first '\r' or '\n'). If it doesn’t hit anything, it stops at the '\0' (returning the length of the string).

Note that this works fine even if there is no newline, because strcspn stops at a '\0'. In that case, the entire line is simply replacing '\0' with '\0'.

Answer #2:

The elegant way:

Name[strcspn(Name, "\n")] = 0;

The slightly ugly way:

char *pos;
if ((pos=strchr(Name, '\n')) != NULL)
    *pos = '\0';
else
    /* input too long for buffer, flag error */

The slightly strange way:

strtok(Name, "\n");

Note that the strtok function doesn’t work as expected if the user enters an empty string (i.e. presses only Enter). It leaves the \n character intact.

There are others as well, of course.

Example- Answer #3:

size_t ln = strlen(name) - 1;
if (*name && name[ln] == '\n') 
    name[ln] = '\0';

Remove trailing newline character from fgets() input Answer #4:

Below is a fast approach to remove a potential '\n' from a string saved by fgets().
It uses strlen(), with 2 tests.

char buffer[100];
if (fgets(buffer, sizeof buffer, stdin) != NULL) {

  size_t len = strlen(buffer);
  if (len > 0 && buffer[len-1] == '\n') {
    buffer[--len] = '\0';
  }

Now use buffer and len as needed.

This method has the side benefit of a len value for subsequent code. It can be easily faster than strchr(Name, '\n')Ref YMMV, but both methods work.


buffer, from the original fgets() will not contain in "\n" under some circumstances:
A) The line was too long for buffer so only char preceding the '\n' is saved in buffer. The unread characters remain in the stream.
B) The last line in the file did not end with a '\n'.

If input has embedded null characters '\0' in it somewhere, the length reported by strlen() will not include the '\n' location.

Answer #4:

Direct to remove the ‘\n’ from the fgets output if every line has ‘\n’

line[strlen(line) - 1] = '\0';

Otherwise:

void remove_newline_ch(char *line)
{
    int new_line = strlen(line) -1;
    if (line[new_line] == '\n')
        line[new_line] = '\0';
}

Answer #5:

For single ‘\n’ trimming,

void remove_new_line(char* string)
{
    size_t length = strlen(string);
    if((length > 0) && (string[length-1] == '\n'))
    {
        string[length-1] ='\0';
    }
}

for multiple ‘\n’ trimming,

void remove_multi_new_line(char* string)
{
  size_t length = strlen(string);
  while((length>0) && (string[length-1] == '\n'))
  {
      --length;
      string[length] ='\0';
  }
}

Removing trailing newline character from fgets() input- Answer #6:

My Newbie way 😉 Please let me know if that’s correct. It seems to be working for all my cases:

#define IPT_SIZE 5

int findNULL(char* arr)
{
    for (int i = 0; i < strlen(arr); i++)
    {
        if (*(arr+i) == '\n')
        {
            return i;
        }
    }
    return 0;
}

int main()
{
    char *input = malloc(IPT_SIZE + 1 * sizeof(char)), buff;
    int counter = 0;

    //prompt user for the input:
    printf("input string no longer than %i characters: ", IPT_SIZE);
    do
    {
        fgets(input, 1000, stdin);
        *(input + findNULL(input)) = '\0';
        if (strlen(input) > IPT_SIZE)
        {
            printf("error! the given string is too large. try again...\n");
            counter++;
        }
        //if the counter exceeds 3, exit the program (custom function):
        errorMsgExit(counter, 3); 
    }
    while (strlen(input) > IPT_SIZE);

//rest of the program follows

free(input)
return 0;
}

Answer #7:

The steps to remove the newline character in the perhaps most obvious way:

  1. Determine the length of the string inside NAME by using strlen(), header string.h. Note that strlen() does not count the terminating \0.
size_t sl = strlen(NAME);

  1. Look if the string begins with or only includes one \0 character (empty string). In this case sl would be 0 since strlen() as I said above doesn´t count the \0 and stops at the first occurrence of it:
if(sl == 0)
{
   // Skip the newline replacement process.
}

  1. Check if the last character of the proper string is a newline character '\n'. If this is the case, replace \n with a \0. Note that index counts start at 0 so we will need to do NAME[sl - 1]:
if(NAME[sl - 1] == '\n')
{
   NAME[sl - 1] = '\0';
}

Note if you only pressed Enter at the fgets() string request (the string content was only consisted of a newline character) the string in NAME will be an empty string thereafter.


  1. We can combine step 2. and 3. together in just one if-statement by using the logic operator &&:
if(sl > 0 && NAME[sl - 1] == '\n')
{
   NAME[sl - 1] = '\0';
}

  1. The finished code:
size_t sl = strlen(NAME);
if(sl > 0 && NAME[sl - 1] == '\n')
{
   NAME[sl - 1] = '\0';
}

If you rather like a function for use this technique by handling fgets output strings in general without retyping each and every time, here is fgets_newline_kill:

void fgets_newline_kill(char a[])
{
    size_t sl = strlen(a);

    if(sl > 0 && a[sl - 1] == '\n')
    {
       a[sl - 1] = '\0';
    }
}

In your provided example, it would be:

printf("Enter your Name: ");

if (fgets(Name, sizeof Name, stdin) == NULL) {
    fprintf(stderr, "Error reading Name.\n");
    exit(1);
}
else {
    fgets_newline_kill(NAME);
}

Note that this method does not work if the input string has embedded \0s in it. If that would be the case strlen() would only return the amount of characters until the first \0. But this isn´t quite a common approach, since the most string-reading functions usually stop at the first \0 and take the string until that null character.

Aside from the question on its own. Try to avoid double negations that make your code unclearer: if (!(fgets(Name, sizeof Name, stdin) != NULL) {}. You can simply do if (fgets(Name, sizeof Name, stdin) == NULL) {}.

Hope you learned something from this post.

Follow Programming Articles for more!

About ᴾᴿᴼᵍʳᵃᵐᵐᵉʳ

Linux and Python enthusiast, in love with open source since 2014, Writer at programming-articles.com, India.

View all posts by ᴾᴿᴼᵍʳᵃᵐᵐᵉʳ →