Home > Mobile >  Need advice (hint) or help create 2 string function
Need advice (hint) or help create 2 string function

Time:06-15

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'
}
  • Related