Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between strncpy and snprintf?

Tags:

c

What is the difference between

strncpy(dst, src, n)

and

snprintf(dst, n, "%s", src)

Should I prefer one or the other when trying to do a bounded string copy? And if so, why?

like image 202
Barry Avatar asked Mar 12 '19 23:03

Barry


People also ask

What's the difference between strncpy and strcpy?

The strcpy function copies string str2 into array str1 and returns the value of str1 . On the other hand, strncpy copies the n characters of string str2 into array str1 and returns the value of str1 .

What is the difference between strncpy and memcpy?

strcpy () is meant for strings only whereas memcpy() is generic function to copy bytes from source to destination location.

What does strncpy return?

The strncpy() function returns a pointer to string1 .

Does strncpy copy null terminator?

The strcpy() function copies string2, including the ending null character, to the location that is specified by string1. The strcpy() function operates on null-ended strings. The string arguments to the function should contain a null character (\0) that marks the end of the string. No length checking is performed.


1 Answers

strncpy is not a bounded strcpy. It's a fixed-length (not bounded, fixed-length) operation targeting a destination that's not a C string (null-terminated) but a null-padded field, like what was used in certain kinds of data record tables in the 70s and early 80s. It has basically no modern purpose and should not be used unless you really want this behavior.

snprintf is the canonical C function for "bounded strcpy". On POSIX systems, strnlen+memcpy would be another good alternative, and necessary if you need to support strings longer than INT_MAX. If you don't have strnlen, you can easily make it with memchr and do the same.

Note that the simple use of snprintf is not "bounded" in the sense of having a bound on how much it reads from the source; it necessarily reads the whole source string to determine the return value, which both can incur a time cost and depends on the source being a valid (terminated) string. If you want it bounded in the sense of both source and destination, you can do something like:

snprintf(dest, n, "%.*s", (int)n-1, src);

However, that's sufficiently non-idiomatic and error-prone that I would just use strnlen and memcpy instead.

like image 155
R.. GitHub STOP HELPING ICE Avatar answered Nov 12 '22 04:11

R.. GitHub STOP HELPING ICE