The function receives two strings str1
and str2
and returns an integer. The function will insert the str2
string at the beginning of the str1
string. When the str1
string size will not change. If the length of the str1
string can contain the entire str2
string, the function will change str1
to contain str2
and then The letters of str1
up to the original length of str1
. In this case the function will return 1
. If the str2
string is longer than str1
, the first letters of str2
will be placed in the str1
string up to str1
, In this case the function will return 0
.
Example 1:
str1 = "abcdefgh" str2 = "xyz"
After running the function:
str1 = "xyzabcde"
And the function will return 1
.
Example 2:
str1 = "abcd" str2 = "efghj"
After running the function:
str1 = "efgh"
And the function will return 0
I started this one
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int string_pre(char *str1, char *str2) {
int sizeStr1 = strlen(str1);
int sizeStr2 = strlen(str2);
}
int main() {
char str1[]= "abcdefgh";
char str2[]= "xyz";
string_pre(str1, str2);
printf("After concatenation: %s %s \n", str1, str2);
printf("After concatenation: %s \n", str2);
return 0;
}
Not sure if this is the correct way to start.
CodePudding user response:
You have a good start. You might use size_t
instead of int
for the string lengths and define str2
as const char *str2
as it is not modified in the function so you can accept constant strings for this argument. Next should come a test if the length of str1
is greater or equal to the length of str2
and appropriate action should be taken in both cases.
Note that your main
function should test multiple cases and print the return value too.
Here is a modified version:
#include <stdio.h>
#include <string.h>
int string_pre(char *str1, const char *str2) {
if (*str2 == '\0') { // quick test for trivial case
return 1;
} else {
size_t sizeStr1 = strlen(str1);
size_t sizeStr2 = strlen(str2);
if (sizeStr1 >= sizeStr2) {
memmove(str1 sizeStr2, str1, sizeStr1 - sizeStr2);
memcpy(str1, str2, sizeStr2);
return 1;
} else {
memcpy(str1, str2, sizeStr1);
return 0;
}
}
}
int main() {
char str1[]= "abcdefgh";
char str2[]= "xyz";
char str3[]= "xyzxyzxyzxyz";
char str4[]= "ABCDEFGH";
int n1 = string_pre(str1, str2);
printf("test1: n1=%d str1='%s' str2='%s'\n", n1, str1, str2);
int n2 = string_pre(str1, str3);
printf("test2: n2=%d str1='%s' str3='%s'\n", n2, str1, str3);
int n3 = string_pre(str1, str4);
printf("test3: n3=%d str1='%s' str4='%s'\n", n3, str1, str4);
return 0;
}
Output:
test1: n1=1 str1='xyzabcde' str2='xyz'
test2: n2=0 str1='xyzxyzxy' str3='xyzxyzxyzxyz'
test3: n3=1 str1='ABCDEFGH' str4='ABCDEFGH'
CodePudding user response:
This should do the work.
however - using strlen to determine the length of a string buffer is normally a bad practice, as you may use buffers that are larger than the actual string they store. a more c way would be to pass on the length of buffer available.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int string_pre(char *str1,char *str2)
{
size_t sizeStr1 = strlen(str1);
size_t sizeStr2 = strlen(str2);
long chars_to_move_right = sizeStr1 - sizeStr2;
size_t chars_to_copy = sizeStr2 > sizeStr1 ? sizeStr1 : sizeStr2;
// have to use memmove since the copying may overlap
if (chars_to_move_right > 0)
{
memmove(str1 sizeStr2, str1, chars_to_move_right);
}
// no overlap expected here, and memcpy may be more efficient.
memcpy(str1, str2, chars_to_copy);
return sizeStr1 >= sizeStr2;
}
int main()
{
char str1[]= "abcdefgh";
char str2[]= "xyz";
printf("Before concatenation: '%s' '%s' \n",str1,str2);
int res = string_pre(str1,str2);
printf("After concatenation: '%s' '%s' \n",str1,str2);
printf("Result = %d\n", res);
return 0;
}
CodePudding user response:
Not sure if this is the correct way to start.
For starters neither declaration from the header <stdlib.h>
is used in your program. So you may remove it.
The second function parameter must be declared with qualifier const
because the corresponding string is not changed within the function.
int string_pre(char *str1, const char *str2);
The return type of the function strlen
is size_t
. So the variables sizeStr1
and sizeStr2
must be declared as having the type size_t
.
size_t sizeStr1 = strlen(str1);
size_t sizeStr2 = strlen(str2);
Now all is ready to fill the body of the function with a code as for example :)
#include <stdio.h>
#include <string.h>
int string_pre( char *s1, const char *s2 )
{
size_t n1 = strlen( s1 );
size_t n2 = strlen( s2 );
int moved_right = n2 < n1;
if ( moved_right )
{
memmove( s1 n2, s1, n1 - n2 );
}
else
{
n2 = n1;
}
memcpy( s1, s2, n2 );
return moved_right;
}
int main( void )
{
char s1[] = "abcdefgh";
char s2[] = "xyz";
int result = string_pre( s1, s2 );
printf( "%d: %s\n", result, s1 );
char s3[] = "abcd";
char s4[] = "efghj";
result = string_pre( s3, s4 );
printf( "%d: %s\n", result, s3 );
}
The program output is
1: xyzabcde
0: efgh
If in case when the both strings are equal each other and you need to return 1 then in this case change this line
int moved_right = n2 < n1;
for example to this line
int moved_right = !( n1 < n2 );
Strictly speaking the function should be declared like
int string_pre(char * restrict str1, const char * restrict str2);
CodePudding user response:
Rather than run the maximum length of both strings, how about iterating no more than the length of the first string?
int replace(char *str1, const char *str2) {
size_t len1 = strlen(str1);
// Search for the null character, but only so far.
const char *end = memchr(str2, '\0', len1);
size_t len2 = (end == NULL) ? len1 : end - str2;
// At this point len2 <= len1
memmove(str1 len2, str1, len1 - len2); // Shift str1
memmove(str1, str2, len2); // Copy in str2
return str2[len2] == '\0'
}