This is just one solution to the problem. There are many others which are
just as correct.
However, it's important to note that this solution is not as portable as
other solutions, because in this solution, strncpy expects the
first string to be pointed at in a particular way.
/* strncpy(s, t, n) copy n chars from s to t. */ #includeint strncpy(char **, char *, int); main(int argc, char *argv[]) { char copy[10]; /* declare array copy to hold the first n chars of s */ /* Preform error checking */ if (argc < 2 || argc > 2) { printf("Errors in input\n"); return 0; /* if there are an invalid number of parameters, terminate */ } strncpy(++argv, copy, 3)); printf("copy is %s\n", copy); } int strncpy(char **string, char *copy, int n) { /*we're traversing each array backwards */ *(copy + n ) = '\0'; /* loop through the arrays */ while (--n >=0) { *(copy + n) = *(*string + n); } return 1; }
strncpy returns an integer, so that it can be used in conditional expressions.
The function takes three arguments. The third parameter is an integer which will be used to determine how many characters to copy from the first to the second array. The second paramater is defined as a pointer to char, the location of the destination array. The first pointer is defined as a pointer to a pointer to char, which is the location of the source string.
It's important to remember that the source and destination arrays are quite different in structure. The destination array is a straight-forward character array, and each character in the array is immediately accessible as an offset from the beginning of the array. However, the first pointer is defined as a pointer to a pointer to char, because we are simply going to pass the pointer to argv which is an array of pointers, where each pointer points to the beginning of a character array holding a command line argument.
C will reserve space for 10 characters. However, because the array is being updated through pointer arithmetic, rather than through array subscripts, C cannot check that a memory address being updated falls within the bounds of the copy array.
In the strncpy() function,we will dyamically use as much space in memory as we need to hold the first characters of the source string, without checking if the bounds of the copy array have been exceeded. Although the function "works", i.e., if we inspect the copy array by printing it, it contains what we expect, there is no guarantee that C will not use the memory addresses just outside the bounds of the array.
Try declaring copy of size 1 and having it store the first 4 characters of the source string to see what happens.
The first parameter to strncpy is a pointer to a pointer to char. argv is such a data type, however if we were to pass argv, then we would send the pointer to the beginning of the array. This would point to the program name, rather than the string we want to process, so prior to passing down the pointer we increment it so that it points to the second array element.
We will take the expression apart to understand what's happening. Remember that the first argument to strncpy() is declared as char **string. In other words, string is a pointer to a pointer to char. From the way strncpy() is called, we know that the first argument is the location in memory of the second element of the argv array, i.e., the array element containing the pointer to the character array containing the input string. *string contains the memory address of start of the input string. *string + n evaluates the memory address of the (nth + 1) character in the input string (because arrays count from 0). So *(*string + n) accesses the contents of that memory location, returning the data contained in the nth array element of the input string.