What is strncpy_s and how to use strncpy_s in C

In this tutorial, you will learn what is strncpy_s and how to use strncpy_s in C programming. I have already written the blog post on why strncpy is unsafe?. If you want, you can also read this blog post it helps you understand why strncpy_s is introduced by the C standard. So let’s understand what is strncpy_s and how to use it in C programming.

What is strncpy_s?

The strncpy_s function introduces in C11. It copies characters of one string to another similar to the strncpy function.

The strncpy_s function copies not more than n successive characters (characters that follow a null character are not copied) from the array pointed to by s2  (Source Buffer) to the array pointed to by s1(Destination buffer). If no null character was copied from s2  , then s1[n] is set to a null character.

Syntax of strncpy_s():

errno_t strncpy_s(char * restrict s1,
                  rsize_t s1max,
                  const char * restrict s2,
                  rsize_t n);

Parameters:

s1 :- Pointer to the destination array where the content is to be copied.
s1max :- The size of the destination buffer.
s2 :- It is a pointer to the source array that will be copied.
:- The first n character copied from src to dest.

Return:

The strncpy_s function returns zero on success, returns non-zero on error.

 

Example of strncpy_s in C:

The following example program shows how we can use stncpy_s in our code. You must remember your compiler should support ISO-C11.

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main()
{
    char src[] = "Aticleworld.com";

    // The destination string size is 16.
    char dest[16] = {0};

    // copying 12 bytes of src into dest.
    strncpy_s(dest, sizeof(dest), src, 12);

    printf("Copied string: %s\n", dest);

    return 0;
}

 

 

Important points related to the strncpy_s function:

1. If n (count) is less than the length of s2 (source array) or if there was no null in the source array, then it writes a null character to s1[n]. It can be used to copy a string without the danger that the result will not be a null-terminated array.

Consider the below example when the length of n is 4 which is less than the length of the src array.

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main()
{
    //source array
    char src[7] = {'g', 'o', 'o', 'd', 'b', 'y', 'e'};

    // The destination array size is 5.
    char dest[5];

    /*
    Call will assign to r the value
    zero and to dst the sequence good\0.
    */
    errno_t r = strncpy_s(dest, 5, src, 4);

    printf("Copied string: %s\n", dest);

    return 0;
}

Output:

good\0

 

2.Unlike strncpy, if n (count) is greater than the length of s2 (source array), the destination string is not padded with null characters up to length n.

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main()
{
    //source array
    char src[12] = "Goodbye";

    // The destination array size is 20.
    char dest[20];

    /*
    Call will assign to r the value
    zero and to dst the sequence Goodbye\0.
    */
    errno_t r = strncpy_s(dest, 20, src, 12);

    printf("Copied string: %s\n", dest);

    return 0;
}

Output:

Goodbye\0

 

3.The strncpy_s function also avoids the overflow issue (characters will not be written end of the destination array).

Consider the below example we will get the non-zero value from strncpy_s because we trying to cross the boundary of the destination array.

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main()
{
    //source array
    char src[7] = {'g', 'o', 'o', 'd', 'b', 'y', 'e'};

    // The destination array size is 10.
    char dest[5];

    /*
     Copy will be overflow, So call will assign to r a nonzero 
     value and to dst the sequence \0.
    */
    errno_t r = strncpy_s(dest, 5, src, 7);//>> return non-zero value

    return 0;
}

 

4. The behavior of strncpy_s is undefined if the source and destination strings overlap.

 

Following are the Runtime-constraints, you must remember:

  • s1 or s2 must not be a null pointer.
  • s1 and s2 must not be overlapped.
  • n is not greater than RSIZE_MAX.
  • s1max is must not be zero or greater than RSIZE_MAX.
  • If n is not less than s1max, then s1max shall be greater than strnlen_s(s2, s1max). Consider the below example,
Example_1: Ok

char src1[100] = "hello";
char dst1[6];
int r1 = strncpy_s(dst1, 6, src1, 100);


Example_2: Error

char src1[4] = "Hi";
char dst1[6];
int r1 = strncpy_s(dst1, 6, src1, 100);

 

Note: If there is a runtime-constraint violation, then if s1 is not a null pointer and s1max is greater than 0 and not greater than RSIZE_MAX, then strncpy_s sets s1[0] to the null character.

 

Recommended Articles for you: