This might be somewhat pointless, but I'm curious what you guys think about it. I'm iterating over a string with pointers and want to pull a short substring out of it (placing the substring into a pre-allocated temporary array). Are there any reasons to use assignment over strncopy, or vice-versa? I.e.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{ char orig[] = "Hello. I am looking for Molly.";
/* Strings to store the copies
* Pretend that strings had some prior value, ensure null-termination */
char cpy1[4] = "huh\0";
char cpy2[4] = "huh\0";
/* Pointer to simulate iteration over a string */
char *startptr = orig + 2;
int length = 3;
int i;
/* Using strncopy */
strncpy(cpy1, startptr, length);
/* Using assignment operator */
for (i = 0; i < length; i++)
{ cpy2[i] = *(startptr + i);
}
/* Display Results */
printf("strncpy result:\n");
printf("%s\n\n", cpy1);
printf("loop result:\n");
printf("%s\n", cpy2);
}
It seems to me that strncopy is both less typing and more easily readable, but I've seen people advocate looping instead. Is there a difference? Does it even matter? Assume that this is for small values of i (0 < i < 5), and null-termination is assured.
Refs: Strings in c, how to get subString, How to get substring in C, Difference between strncpy and memcpy?
strncpy(char * dst, char *src, size_t len)
has two peculiar properties:
(strlen(src) >= len)
: the resulting string will not be nul-terminated.(strlen(src) < len)
: the end of the string will be filled/padded with '\0'.The first property will force you to actually check if (strlen(src) >= len)
and act appropiately. (or brutally set the final character to nul with dst[len-1] = '\0';
, like @Gilles does above) The other property is not particular dangerous, but can spill a lot of cycles. Imagine:
char buff[10000];
strncpy(buff, "Hello!", sizeof buff);
which touches 10000 bytes, where only 7 need to be touched.
My advice:
memcpy(dst,src,len); dst[len] = 0;
Since for safe operation the strncpy() version already needs to know the sizes, (and the checks on them!), the memcpy() version is not more complex or more dangerous than the strncpy() version. (technically it is even marginally faster; because memcpy() does not have to check for the '\0' byte)
While this may seem counter-intuitive, there are more optimized ways to copy a string than by using the assignment operator in a loop. For instance, IA-32 provides the REP
prefix for MOVS
, STOS
, CMPS
etc for string handling, and these can be much faster than a loop that copies one char at a time. The implementation of strncpy
or strcpy
may choose to use such hardware-optimized code to achieve better performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With