0

I was recently trying to find the size of an input C string buffer for using it in memcpy to copy the contents of the input buffers to the output buffer without overlapping. The following is the code snippet.

char * func(char *buff1, char *buff2, char *outbuff)
{
    int size = 0;
    while(*buff1 != '\0')
     {
       size++;
       buff1++;
     }
   memcpy(outbuff, buff1, sizeof(char)*size);
   memcpy(outbuff + size, buff2, sizeof(char)*size);
   return outbuff; 
}

However, I found out that this is a very inefficient way of finding size. If you guys know about any other alternatives it would be very helpful to me.

Edit: I am not allowed to pass their sizes as separate parameters.

9
  • 2
    Likely the most efficient would be to remember the size, when you fill the input buffer, in a separate variable and pass it as an additional parameter to func. Commented Jun 1, 2020 at 10:48
  • 2
    I am not not able to pass their sizes as separate parameters. — Why not? Commented Jun 1, 2020 at 10:51
  • @DanielLangr This is what is the requirement given to me. Can we do it in a more efficient way without using while loop?. Commented Jun 1, 2020 at 10:53
  • @user207421 efficient in the sense that without using any loop, like more of a vectorized manner. Commented Jun 1, 2020 at 10:56
  • 2
    @SauravRai First, we would need to know your assignment and requirements for its solution. Also, please, create a minimal reproducible example we could run. BTW, what do you think that buff1 points to after the while loop? Commented Jun 1, 2020 at 10:56

3 Answers 3

2

There's no solution to your problem. You ask for something like a vector, but vectors only know their size because they store it. Since it seems you aren't allowed to change the signature of your function then a loop is your only alternative. In any case it doesn't seem that inefficient to me.

Your code does have bugs, when you are calculating the size of buff1 you adjust the buff1 pointer, so that is no longer points to the start of the block when you do the copy. You need to substract the size of the buffer before you copy. Also you seem to be assuming that your two input buffers are the same size.

This would seem to be a better version of your code.

char* func(char *buff1, char *buff2, char *outbuff)
{
    int size1 = 0;
    while (*buff1 != '\0')
    {
        size1++;
        buff1++;
    }
    int size2 = 0;
    while (*buff2 != '\0')
    {
        size2++;
        buff2++;
    }
    memcpy(outbuff, buff1 - size1, sizeof(char)*size1);
    memcpy(outbuff + size1, buff2 - size2, sizeof(char)*size2);
    return outbuff; 
}

You could use strlen which does the same thing as the code above, but strlen is a loop as well. So the advantage of using strlen is not that you are avoiding a loop, only that the code is a little easier to understand.

#include <cstring>

char* func(char *buff1, char *buff2, char *outbuff)
{
    int size1 = strlen(buff1);
    int size2 = strlen(buff2);
    memcpy(outbuff, buff1, sizeof(char)*size1);
    memcpy(outbuff + size1, buff2, sizeof(char)*size2);
    return outbuff; 
}

Then finally you could use strcpy and strcat, which also have similar effect

#include <cstring>

char* func(char *buff1, char *buff2, char *outbuff)
{
    strcpy(outbuff, buff1);
    strcat(outbuff, buff2);
    return outbuff; 
}

This apparently avoids any loops and size calculations at all. But of course they are still happening, just internally to the strcpy and strcat functions.

There is one difference between this latest version and the two previous versions. The version with strcpy and strcat also copies the terminating '\0' character to outbuff, so outbuff will be null temrinated just ilke you are assuming that buff1 abd buff2 are. This seems like an advantage to me, but you might not agree.

Sign up to request clarification or add additional context in comments.

1 Comment

func() fails to form a string as outbuff lacks a null character. Yet perhaps OP wants that. Hmmmm.
2

to copy the contents of the input buffers to the output buffer without overlapping.

As copying is the goal, "I found out that this is a very inefficient way of finding size." is misguided.

The efficiency is O(n) even if finding the size could be done without a loop as the copy takes O(n). "very inefficient" belongs to cases when the O() is worse.


Rather than run down the strings twice, once is sufficient as buffers are non-overlapping.

char * func(const char *buff1, const char *buff2, char *outbuff) {
  char *dest = outbuff;
  while(*buff1) {
    *dest++ = *buff1++;
  }
  while(*buff2) {
    *dest++ = *buff2++;
  }

  // more common to append a \0
  *dest = '\0';

  return outbuff; 
}

Comments

0

C strings are null terminated arrays of characters. If your function handles legitimate C strings, then you should use the standard string library. For example, strlen(src), strcpy(dst,src) etc. Since it is sometimes the case that strings violate the property of ending with 0, the standard string library offers functions like strncpy(dst,src,n) where copy is performed until the null terminating character, as long as the number of characters copied is at most n.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.