strncpy does not store characters properly C

148 Views Asked by At

Basically, I use strncpy to truncate the characters if it is greater than the character array size.

So, I have the following variables and methods.

char studentName[6];
char colour[5];
char music[7];

strcpy(this->studentName, "null");
strcpy(this->colour, "null");
strcpy(this->music, "null"):

void setName (char* studentName)
{
 strncpy(this->studentName, studentName, 6);
 this->studentName[6] = '\0'; // SET LAST TO NULL POINTER
}

void setColour (char* colour)
{
 strncpy(this->colour, colour, 5);
 this->colour[5] = '\0'; // SET LAST TO NULL POINTER
}

void setMusic (char* music)
{
 strncpy(this->music, music, 7);
 this->music[7] = '\0'; // SET LAST TO NULL POINTER
}

So, if I set the student name to Jackson, it will truncate to Jackso, however, my colour variable will be blank and my music variable will be null.

Also, if I try...

void setName (char* studentName)
{
  strncpy(this->studentName, studentName, 6);
  this->studentName[6-1] = '\0'; // SET LAST TO NULL POINTER
}

void setColour (char* colour)
{
 strncpy(this->colour, colour, 5);
 this->colour[5-1] = '\0'; // SET LAST TO NULL POINTER
}

void setMusic (char* music)
{
 strncpy(this->music, music, 7);
 this->music[7-1] = '\0'; // SET LAST TO NULL POINTER
}

and I set the student name to Jackson I get something like Jacksonull. It adds null to the end

2

There are 2 best solutions below

0
On

Here (assumes Linux platform. You might have to fetch strlcpy implementation if your on Windows, not sure.)

#include <bsd/string.h>

char studentName[6]; /* Good to know: Globals are initialized to zero */
char colour[5];
char music[7];

/* Pretty useless function since a single strlcpy call is enough */
static size_t setX(char *buf, size_t buflen, const char *new_val) {
    return strlcpy(buf, new_val, buflen);
}

int main(int argc, char **argv) {
    setX(studentName, 6, "Peter");  /* Please read man page and check return value */
}

Now strlcpy guarantees NUL termination as long as length argument is >0.

15
On

Try using sizeof() instead of raw numbers. It allows you to change array's sizes without touching your code.

You first copy sizeof(array)-1 symbols and then set the last symbol which is of index sizeof(array)-1 (because indexing starts from 0) to '\0'.

Your code edited would look like this:

char studentName[6];
char colour[5];
char music[7];

strcpy(this->studentName, "null");
strcpy(this->colour, "null");
strcpy(this->music, "null"):

void setName (char* studentName)
{
 strncpy(this->studentName, studentName, sizeof(this->studentName)-1); // Copy n-1 chars
 this->studentName[sizeof(this->studentName)-1] = '\0'; // n is set to null symbol
}

void setColour (char* colour)
{
 strncpy(this->colour, colour, sizeof(this->color)-1);
 this->colour[sizeof(this->color)-1] = '\0'; 
}

void setMusic (char* music)
{
 strncpy(this->music, music, sizeof(this->music)-1);
 this->music[sizeof(this->music)-1] = '\0'; 
}