Search code examples
cstringstrncpy

Strncpy() string length output error


I am having a problem with strncpy() copying an extra character at the length I need. I need to copy the 10 most significant bits from one string to another (both in char* format).

The size of the larger variable does not intuitively matter, and the smaller only affects the output when it is significantly smaller than the value I need (I don't know why this is either).

The n value in my strncpy() may be what's causing the problem, but I have no idea why it's acting the way it is. If I'm not mistaken, n, the length of the destination string, should be 1 longer than the data, to account for the null character at the end.

My string is not behaving this way at all. Setting n to 11, I receive the following output:

00000111101100100100001110100000

00000111101

I would imagine it would only copy 10 characters, with the final one for the null. Increasing n produces the same results.

Decreasing n to 10 reveals the heart of the problem:

00000111101100100100001110100000

0000011110@

I don't know why it would do this, but it continues to do this as n decreases, until n is much smaller (around 8).

These are the relevant lines of my code:

char line[11], hexAddr[8], binAddr[33], lv1Index[11];
    ...
strncpy(lv1Index, binAddr, 10);

where lv1Index was untouched before this, and binAddr is displayed (in the given output) directly beforehand.

The added character is always @, so I don't believe it's garbage from lv1Index pre-initialization.


Solution

  • From one C++ reference:

    If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.

    No null-character is implicitly appended to the end of destination, so destination will only be null-terminated if the length of the C string in source is less than num.

    Other documentation (MSDN, man page) has similar information.

    This means you should put the null terminator on yourself:

     lv1Index[10] = '\0';