Videos
You can use pointer arithmetic and the function memcpy:
#include <stdio.h>
#include <string.h>
int main( void )
{
char str1[] = "123copy321";
char str2[5];
//copy str1[3] up to and including str1[6] to str2
memcpy( str2, str1 + 3, 4 );
//add terminating null character to str2
str2[4] = '\0';
printf( "%s\n", str1 );
printf( "%s\n", str2 );
}
This program has the following output:
123copy321
copy
With theFunctionINeed(str1, str2, 3, 6); there are a number of issues:
Source string may be less than 3.
Available sub-string length may be less than 4.
Destination array may be too small.
Unusual to pass in the first and last index to copy. This prevents forming a zero-length sub-string. More idiomatic to pass in beginning and 1) length or 2) index of one-past.
How about returning something useful, like was the destination big enough?
Alternative untested sample code follows. restrict means the two pointers should not point to overlapping memory.
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
// Return `destination` when large enough
// otherwise return NULL when `size` was too small.
bool SubString(size_t destination_size, char *restrict destination,
const char *restrict source, size_t offset, size_t length) {
if (destination_size == 0) {
return NULL;
}
destination[0] = '\0';
// Quickly search for the null character among the first `offset` characters of the source.
if (memchr(source, '\0', offset)) {
return destination;
}
destination_size--;
size_t destination_length = length <= destination_size ? length : destination_size;
strncat(destination, source + offset, destination_length);
return length <= destination_size ? destination : NULL;
}
Just add your offset to the str1 argument of the strncpy call. For example:
strncpy(str2, str1 + 1, 5);
will copy five bytes into str2 from str1 starting at index 1.
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "this is a test";
char str2[20];
char str3[30];
strncpy( str2, str1, 5 );
str2[5] = '\0';
strncpy( str3, str1 + 1, 5 );
str3[5] = '\0';
//...
}
Here is a more complete example
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "this is a test";
char str2[sizeof( str1 ) - 5][6];
const size_t N = sizeof( str1 ) - 5;
size_t i;
for ( i = 0; i < N; i++ )
{
strncpy( str2[i], str1 + i, 5 );
str2[i][5] = '\0';
}
for ( i = 0; i < N; i++ )
{
puts( str2[i] );
}
return 0;
}
The output is
this
his i
is is
s is
is a
is a
s a t
a te
a tes
test
You're incrementing dest during the while loop. You need to keep hold of a pointer to the start of the buffer to return from the function.
char *stringcopywithpointer( const char *source)
{
int ii = 0;
int len = strlen(source);
char *copy = malloc(len+1);
char* dest = copy;
while(*source != '\0')
{
*dest++ = *source++;
}
*dest = '\0';
printf("\n copied string = %s", copy);
return copy;
}
Note that you could save some code by using strcpy
char *stringcopywithpointer( const char *source)
{
int len = strlen(source);
char *copy = malloc(len+1);
strcpy(copy, source);
return copy;
}
and you could reduce this to a single line if you have access to the non-standard strdup
char *stringcopywithpointer( const char *source)
{
return strdup(source);
}
My opinion:
Avoid allocate memory in called function, better allot memory before calling a function
char *dest = ( char* ) malloc( sizeof( char ) * len ); // doesn't looks great
Irrespective of the machine, sizeof( char ) is always 1 byte. Less redundant is sizeof( char ) * len. Optimal would be malloc( sizeof( source ) ).
Pointers and arrays are related You can either use
dest[i] = src[i];
*dst++ = *src++;
or
// assuming dst memory allocate by caller
while ( *dst++ = *src++);