2

I have

char aa[] = { "Hello, !" };

char bb[] = { "World" };

How to insert bb into aa the most efficiently with cstring ?

Pythagoras of Samos
  • 3,051
  • 5
  • 29
  • 51
  • **Why** would you rather use cstring? – SLaks Nov 21 '10 at 21:36
  • Why have you got both `C` and `C++` tags ? It sounds like this is a C++ question, not a C question ? – Paul R Nov 21 '10 at 21:37
  • The most optimal and fast way to insert "World" into "Hello, !" to make "Hello World!" is to hard-code it: `char cc[] = "Hello, World!"`. I'm assuming you meant to word it differently though! – Stuart Golodetz Nov 21 '10 at 21:39
  • when I compare 500 strings using std::string, my FPS (when I render a 3d scene) drops down from 3800 to ~1600. With strcmp, it drops down to ~3600. – Pythagoras of Samos Nov 21 '10 at 21:39
  • 1
    @Glorian: Are you measuring in debug or release mode? – fredoverflow Nov 21 '10 at 21:45
  • 1
    @Glorian: I would bet you're optimizing the wrong piece of code; if you really want to use strcmp that much, then use C++ string and do `strcmp(a.c_str(), b.c_str())` or `a.compare(b)`; however, I'd bet that string comparison is not the problem here. – Lie Ryan Nov 21 '10 at 21:47
  • 1
    I removed the tag to C++. It's seems redundant. While he might be using C++, if he isn't going to use any C++ features, it's basically C. – Dominic K Nov 21 '10 at 21:47

4 Answers4

10
  • allocate big enough buffer (malloc/new[])
  • copy the first part of the aa string into the buffer (strncpy/memcpy)
  • copy the bb string (strcpy/memcpy)
  • copy the rest of the aa string (strncpy/memcpy)
Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151
7

Maximum optimization usually requires taking advantage of the specific requirements. You make the code less general to gain speed (or some other metric). You may know some corner you can cut, while we have to guess.

Code fragments below use these headers:

#include <stdio.h>
#include <string.h>

If you want to maximize performance, it would help to pre-allocate enough space for the final string, post- insert:

#define MAX_STR_LEN 256 

char aa[MAX_STR_LEN] = "Hello, !";
char bb[] = "World";

You don’t indicate how you know where to insert. For my sample code I define the insert point as an offset into the destination string:

size_t pos = 7;

If you know either of the string lengths in advance you should use a const instead of calling strlen, which has to scan the string. Here I don’t’ assume you’re that lucky.

size_t srclen = strlen(bb);

The memmove function properly handles overlapping source and destination:

//  +1 for count to include terminating null
memmove(aa+pos+srclen, aa+pos, strlen(aa)-pos+1);

memcpy is faster on some platforms and can be safely used to copy between strings:

memcpy(aa+pos, bb, srclen);

Now aa contains the result.

If you can’t pre-allocate aa to the required size, then:

// additional include for malloc
#include <stdlib.h>

char aa[] = "Hello, !";
char bb[] = "World";
size_t pos = 7;    

size_t srclen = strlen(bb);
size_t dstlen = strlen(aa);
char *m = malloc(srclen+dstlen+1);
// Test for NULL or use an allocator that throws

memcpy(m, aa, pos);
memcpy(m+pos, bb, srclen);
memcpy(m+pos+srclen, aa+pos, dstlen-pos+1);

m contains the result and probably needs to be free'd eventually.

Remember if there is any chance for buffer overflow, you have to check lengths to avoid memory corruption and a possible security vulnerability.

I hope this helps.

jimhark
  • 4,938
  • 2
  • 27
  • 28
3
std::string aa = "Hello, !";
std::string bb = "World";
aa.insert(7, bb);

dont wanna use string from C++

Then why are you tagging this as C++?

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
0

char *newStr = malloc(strlen(aa) + strlen(bb));

sprintf(newStr, "%s%s", aa, bb);

kchoi
  • 473
  • 1
  • 4
  • 11