3

I have written a function to wrap GNU getline() and remove the trailing newline, but for some reason it has no effect. Am I doing something wrong?

ssize_t readline(char **lineptr, FILE *stream)
{
  size_t len = 0;  // Size of the buffer, ignored.

  ssize_t chars = getline(lineptr, &len, stream);

  if((*lineptr)[chars] == '\n') {
    (*lineptr)[chars] = '\0';
    --chars;
  }

  return chars;
}

It compiles and links without problems, but the newline is not replaced with a null-terminator. I've verified the if() statement is running. Thanks for any help!

James
  • 1,430
  • 4
  • 20
  • 27

2 Answers2

12

getline returns the number of characters read. So you have to use chars-1 rather than char.

if ((*lineptr)[chars - 1] == '\n') 
  {
      (*lineptr)[chars - 1] = '\0';
      --chars;
  }

man getline (3)

On success, getline() and getdelim() return the number of characters read, including the > delimiter character, but not including the terminating null byte. This value can be used to handle embedded null bytes in the line read.

md5
  • 23,373
  • 3
  • 44
  • 93
4

You want to check and replace the last character, not the one after it.

if ((*lineptr)[chars - 1] == '\n') {
    (*lineptr)[chars - 1] = '\0';
}

(getline() returns the number of characters read, just as strlen() returns the length of a string, excluding the terminating 0 character.)