Write versions of the library functions
strncpy
,strncat
andstrncmp
, which operate on the mostn
characters of their argument strings. For example,strncpy(s, t, n)
copies at mostn
characters oft
tos
. Full Description in Appendix B.
Here is my implementation of strncmp
:
int custom_strncmp(const char *s, const char *t, size_t n) {
while(n--) {
if(*s != *t) {
return *s - *t;
}
else {
++s;
++t;
}
}
return 0;
}
The while
loop will run until n
reaches the value 0
, or until the characters that s
and t
point to are not equal. At each iteration I check if the *s
and *t
are equal; if they are, I increment s
and t
. If they are not equal, I return their difference.
After the loop stops, the value 0
is returned.
Here is my implementation of strncat
:
char *custom_strncat(char *s, const char *t, size_t n, size_t bfsize) {
size_t slen = strlen(s);
char *pend = s + slen;
if(slen + n >= bfsize)
return NULL;
while(n--)
*pend++ = *t++;
return s;
}
This version of strncat
is a secure one. The first if-statement
checks if there is enough space in the s
buffer to store the contents of t
. The while
loop will run until n
reaches the value 0
. At each iteration the value that t
points to is copied in to *s
.
After the loop stops, is returned a pointer to the result.
Here is my implementation of strncpy
:
char *custom_strncpy(char *s, const char *ct, size_t n) {
char *saver = s;
while(n--)
*saver++ = *ct++;
*saver = '0円';
return s;
}
The while
loop will run until n
reaches the value 0
, at each iteration the current character that ct
points to is copied in *saver
. After the loop stops, the '0円'
is copied in *saver
and a pointer to the result is returned.
The exercise can be found at page 121 in K&R second edition.
2 Answers 2
I think you've misinterpreted the definition of strncat, which says,
Appends the first
num
characters of source to destination, plus a terminating null-character. If the length of the C string in source is less thannum
, only the content up to the terminating null-character is copied.
n
is the maximum number of characters in source you you want to copy, and bfsize
doesn't exist in the standard version of strncat
.
char destination[256];
strpy(destination, "foo");
strncat(destination, "bar", 2);
// expect destination should now contain "fooba" !
It's good of you to write a custom version with an extra parameter to make it safe, but that's not what the question asked for.
See also Manual Reference Pages - Strn (3) (e.g. Strncat
instead of strncat
); or, the Microsoft versions of the 'safe' functions have _l
as a suffix.
I'm not sure that returning null and doing no copy is the standard way to avoid buffer overflow.
In your custom_strncmp
method, I'm not sure what correct behaviour should be if you call
strncmp("foo", "foo", 10);
Your function might return 0 or non-zero, or crash, depending on what's after the end of the string.
You could perhaps write it more elegantly as a for loop:
for ( ; n--; ++s, ++t) {
if(*s != *t) {
return *s - *t;
}
}
In custom_strncat
you don't handle the condition where n > strlen(t)
.
Your parameters could (should) be better named, e.g. source
and destination
. Parameter names are important (even more important than good names for local variables) because they may be the only documentation about how the function should be called.
Years later, but for completeness ... custom_strncpy
above is not compatible with standard strncpy
.
- It writes
n+1
characters into destination (onlyn
is correct). - It reads past
0円
of source string. - It does not
0円
-pad destination string if source is smaller. - it always
0円
terminates. (strncpy will not in case strlen(source)>=s
).