I've been tried to place each character in the source string between characters in the destination string. It worked with equal length words but it didn't work other situations
For example:
It worked between apple
and fruit
, result is afprpuliet
.
But it didn't work between plane
and yes
, the result should have been pyleasne
.
or fly
and train
, the result should have been ftlryain
.
Here is my code:
#include <stdio.h>
#include <string.h>
#define DESTSIZE 100
#define SOURCESIZE 20
int main(void)
{
char destination [DESTSIZE], source [SOURCESIZE];
printf("enter destinantion string for strinsert: ");
scanf("%s", destination);
printf("enter source string for strinsert: ");
scanf("%s", source);
strinsert(destination, source);
printf("after strinsert, destination string is %s\n", destination);
return 0;
}
void strinsert(char destination[], char source [])
{
int dest_len = strlen(destination);
for (int i = dest_len - 1; i >= 0; i--) {
destination[2 * i] = destination[i];
}
for (int i = 0; i < dest_len; i ) {
destination[2 * i 1]= source[i];
}
}
CodePudding user response:
To do this "in place" (using an adequately sized destination array) is not hard. The key is to determine the index of the destination element, then start copying, one by one, from the longest of the two strings, right to left.
Subtle is that when the two lengths yet to be copied are the same value, the second array is used as the source, not the first.
#include <stdio.h>
#include <string.h>
char *merge( char s1[], char s2[] ) {
int l1 = strlen( s1 );
int l2 = strlen( s2 );
s1[ l1 l2 ] = '\0'; // ensure string will be terminated
while( l1 || l2 )
if( l1 > l2 )
l1--, s1[ l1 l2 ] = s1[ l1 ];
else
l2--, s1[ l1 l2 ] = s2[ l2 ];
return s1;
}
int main( void ) {
char dest[100];
char *test[] = { "apple", "fruit", "plane", "yes", "fly", "train", };
const int nTest = sizeof test/sizeof test[0];
for( int i = 0; i < nTest; i = 2 ) {
printf( "%s << %s = ", test[i], test[i 1] );
strcpy( dest, test[i] );
puts( merge( dest, test[i 1] ) );
}
return 0;
}
apple << fruit = afprpuliet
plane << yes = pyleasne
fly << train = ftlryain
A more compact version of main()
so that it doesn't draw so much attention:
int main( void ) {
char d[100], *t[] = { "apple", "fruit", "plane", "yes", "fly", "train", };
for( int i = 0; i < sizeof t/sizeof t[0]; i = 2 )
printf("%s << %s = %s\n", t[i], t[i 1], merge(strcpy(d, t[i]), t[i 1]));
return 0;
}
EDIT
Although this is more difficult for a human to read, merge()
could, likewise, be made more compact. It's up to the reader to decide if this appeals to their taste.
char *merge( char s1[], char s2[] ) {
int l1 = strlen( s1 ), l2 = strlen( s2 );
char *p = s1 l1 l2;
*p = '\0';
while( l1 || l2 )
*--p = ( l1 > l2 ) ? s1[ --l1 ] : s2[ --l2 ];
return p;
}
CodePudding user response:
The problem is here
for (int i = 0; i < dest_len; i ) {
destination[2 * i 1]= source[i];
}
Your source length is only 20 characters but your destination length is 100. So you are reading past the bounds of the source array. You should change the second loop to something like
int src_len = strlen(source);
for (int i = 0; i < src_len; i ) {
destination[2 * i 1]= source[i];
}
CodePudding user response:
I think you are messing yourself up by trying to do it in-place. Sure, it can be done in-place, but that just adds complexity.
Try doing it with a destination
that is not either of the sources.
void interleave_strings( char * dest, const char * src1, const char * src2 )
{
// Interleaves src1 and src2 and stores the result in dest.
// dest must have space for strlen(src1) strlen(src2) 1 characters.
}
Usage:
int main(void)
{
char destination[SOURCE_SIZE*2 1] = {0};
char source1[SOURCE_SIZE] = {0};
char source2[SOURCE_SIZE] = {0};
...
interleave_strings( destination, source1, source2 );
printf( "interleaved = \"%s\"\n", destination );
return 0;
}
Once you make sense of doing it that way, then you can totally go back and do it the harder in-place way.
Oh, BTW, functions beginning with “str
” are reserved. Hence you should not create them. So I renamed it.
CodePudding user response:
- You overwrite existing data in the destination. The easiest way is to use temporary array:
char *merge(char *dest, const char *src)
{
char temp[strlen(dest) strlen(src) 1];
char *wrk = dest;
size_t index = 0;
while(*src | *dest)
{
if(*dest) temp[index ] = *dest ;
if(*src) temp[index ] = *src ;
}
memcpy(dest, temp, index);
dest[index] = 0;
return dest;
}
int main(void)
{
char dest[256] = "1234567890";
char *src = "abcdefghijklmno";
puts(merge(dest, src));
}
https://godbolt.org/z/sqznjMf6r
or with your examples:
int main(void)
{
puts(merge((char[128]){"apple"}, "fruit"));
puts(merge((char[128]){"pen"}, "paper"));
puts(merge((char[128]){"plane"}, "yes"));
puts(merge((char[128]){"fly"}, "train"));
}