cstringnestedtrimstrncpy

Using strncpy() where destination contains the source


I wrote a function to trim white space characters from a string in C. My concern is the last line in the trim() function below, where the source is contained in the destination. The test cases all turned out fine, along with some other testing. Can copying all or a portion of a string where the source and destination are in the same memory cause weird problems?

Source code:

#include <stdio.h>
#include <string.h>

void trim(char *line)
  {
  int  i, len = strlen(line);
  char *ptr, whitespace[] = " \t\n";

  // scan for first char which does not match a char in whitespace string
  for (i=0; i<len; i++)
    if (strchr(whitespace, line[i]) == NULL)
      break;
  ptr = line + i;

  // scan for last char which does not match a char in whitespace string
  for (i=len; i>0; i--)
    if (strchr(whitespace, line[i]) == NULL)
      break;
  line[i] + 1) = '\0';

  // copy result to line (this is the line relevant to the question)
  strncpy(line, ptr, len);
  }

int main(void)
  {
  int i;
  char test[4][64] = {
    "a line with no leading and trailing spaces",
    "  a line with some leading and trailing spaces  ",
    "\ta line with leading and trailing tabs\t",
    "\na line with leading and trailing newlines\n"
    };

  for (i=0; i<4; i++)
    {
    printf("test %d\nno trim: %s\n", i, test[i]);
    trim(test[i]);
    printf("trimmed: %s\n", test[i]);
    }
  return 0;
  }

Solution

  • If you read e.g. this strncpy reference you will see

    The behavior is undefined if the character arrays overlap.

    You need to use memmove instead, which is specified to handle overlapping memory.