Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

C++

Name: Anon 2009-01-28 2:07

Hey, I am a complete noob to c++, and I need to know how to add strings.

Eg, I have:
a="one"
b="two"
c="three"

and I would like "d" to equal "onetwothree".

Thank you for any help

Name: Anonymous 2009-01-28 2:08


#include <string>
using namespace std;

string d = a + b + c;

Name: Anonymous 2009-01-28 2:10

CONCATENATION

Name: Anonymous 2009-01-28 5:53

Name: Anonymous 2009-01-28 8:20

#include <stdlib.h>

char* a="one";
char* b="two";
char* c="three";
char* d=malloc(sizeof(char)*(strlen(a)+strlen(b)+strlen(c)+1));

strcpy(d,a);
strcpy(*d+strlen(a),b);
strcpy(*d+strlen(a)+strlen(b),c);

Name: Anonymous 2009-01-28 12:34

#define A "one"
#define B "two"
#define C "three"

(const?) char *d = A B C;

Name: Anonymous 2009-01-28 12:37

>>5
*d+strlen(a)
wat?

Name: Anonymous 2009-01-28 12:40

>>7
Anonix extension to the C Programming Language.

Name: Anonymous 2009-01-28 13:37

>>7
Perhaps that should read
   *(d+strlen(a))
or is it
   d[strlen(a)]

This language is terrible

Name: Anonymous 2009-01-28 14:02

>>9
It should be just d+strlen(a), and no, it's not the fault of language, it's just that you are dumb.

Name: Anonymous 2009-01-28 14:33

>>5
 * sizeof(char) is defined by the standard to be 1.
 * strcpy is not the proper function to use in this situation.
 * Using strcat requires calloc instead of malloc to be used to ensure NULL-termination.

The corrected code has been attached to this message.
____________________________
Attachments:

#include <stdlib.h>

char *a="one";
char *b="two";
char *c="three";
char *d=calloc(strlen(a)+strlen(b)+strlen(c)+1, 1);

strcat(d, a);
strcat(d, b);
strcat(d, c);

Name: Anonymous 2009-01-28 15:09

>>11
Calloc will null all the memory while you only need one first byte for strcat. The way you use strcat is not optimal either.
I mean, if you care about speed, write it so that it works fast, and if you don't - don't use C.

Name: Anonymous 2009-01-28 15:20

>>12
The way you use strcat is not optimal either.
Please provide evidence to support, citing gcc-produced assembly for reference.

I mean, if you care about optimizations, examine it in the form that it's executed, and if you don't - don't critique my C.

Name: Anonymous 2009-01-28 15:29

#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>

#define NOW() (gettimeofday(&here,NULL), \
    (here.tv_sec-there.tv_sec)*1000+(here.tv_usec-there.tv_usec)/1000)

#define HOWMANY 4000000

main(){
    int now,then;
    int i;
    struct timeval here,there;
   
    char
        *a="one",
        *b="two",
        *c="three";
   
    char *d;

    gettimeofday(&there,NULL);
   
    then=NOW();
    for(i=0;i<HOWMANY;i++){
        d=malloc((strlen(a)+strlen(b)+strlen(c)+1));
       
        strcpy(d,a);
        strcpy(d+strlen(a),b);
        strcpy(d+strlen(a)+strlen(b),c);
    }
    now=NOW();
    printf(">>5 took %d ms\n",now-then);

    then=NOW();
    for(i=0;i<HOWMANY;i++){
        d=calloc(strlen(a)+strlen(b)+strlen(c)+1, 1);
        strcat(d, a);
        strcat(d, b);
        strcat(d, c);
    }
    now=NOW();
    printf(">>11 took %d ms\n",now-then);

    then=NOW();
    for(i=0;i<HOWMANY;i++){
        volatile unsigned int la,lb,lc;
       
        la=strlen(a);
        lb=strlen(b);
        lc=strlen(c);
       
        d=malloc(la+lb+lc+1);
       
        strcpy(d,a);
        strcpy(d+la,b);
        strcpy(d+lb+lc,c);
    }
    now=NOW();
    printf(">>14 took %d ms\n",now-then);
}


Did not expect this:
>>5 took 1550 ms
>>11 took 1369 ms
>>14 took 1103 ms

Name: Anonymous 2009-01-28 15:31

>>11
"There is at least one DSP I have worked with where CHAR_BIT is 32. The char types, short, int and long are all 32 bits." - From http://home.att.net/~jackklein/c/inttypes.html

Name: Anonymous 2009-01-28 15:34

>>13
After first strcat your string will be "one". When you call strcat the second time, it will have to walk this "one" string to find where it ends and where to append your "two". Third call will have to walk "onetwo" to find its end. You don't need that, you already know when string ends when you append something to it. I'm not going to provide assembly, look at the benchmark one post higher.

Name: Anonymous 2009-01-28 15:36

>>15
Missing the point, sizeof(char) is always 1.

Name: Anonymous 2009-01-28 15:58

>>17
1 what?

Name: Anonymous 2009-01-28 16:20

>>18
1 number, that number being 1.

Name: Anonymous 2009-01-28 16:26

>>19
Thou shalt countest not past 1?

Name: Anonymous 2009-01-28 17:22

>>10
It should be just d+strlen(a)
d :: char*
strlen(a) :: size_t
d + strlen(a) :: char* + size_t
                    => ??????

Name: Anonymous 2009-01-28 17:51

>>16
Note that strcat in >>14 walking the length of the string is no different from strlen walking the length of the string in >>11, except that it's more clear to the compiler what you're doing (thus enabling additional optimizations, as shown by the performance increase noted in >>14).

The reason assembly was asked for is because gcc, at least, provides internal implementations for most of the string functions (if -fno-builtins isn't specified, all functions used in this thread are builtins) and does some naughty stuff to decrease runtimes[1].
                         
References:
[1] http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Other-Builtins.html

Name: Anonymous 2009-01-28 18:44

>>22
naughty stuff
That filthy gcc

Name: Anonymous 2009-01-28 18:44

>>22
naughty stuff
That filthy gcc

Name: Anonymous 2009-01-28 21:02

>>23,24
Same person.

Name: Anonymous 2009-01-28 21:11

>>25
No kidding.

Name: Anonymous 2009-01-29 2:54

>>22
Even with your naughty optimizations result are still worse than with the last solution, which is just a slight modification of >>5, who thought that subexpression elimination can be applied here (dumbass). You can't make it work that fast using strcat.

Name: Anonymous 2009-01-29 3:38

char *d = malloc(strlen(a) + strlen(b) + strlen(c)), *t = d;
while(*t++ = *a++);
--t;
while(*t++ = *b++);
--t;
while(*t++ = *c++);

Name: Anonymous 2009-01-29 3:48

>>28
What the fuck. You took the lengths of all three strings, and then didn't bother doing the obvious next step and using them.

In the majority case, strcat is much faster then a naive character-by-character copy.

Name: Anonymous 2009-01-29 3:56

If you need extra speed you can always use arrays.

Name: Anonymous 2009-01-29 4:11

size_t al = strlen(a), bl = strlen(b), cl = strlen(c);
char *d = malloc(al + bl + cl + 1);
memcpy(d, a, al);
memcpy(d + al, b, bl);
memcpy(d + al + bl, c, cl);
*(d + al + bl + cl) = 0;


Or, since OP asked about Sepples:
std::string a = "one", b = "two", c = "three", d = a + b + c;

Name: Anonymous 2009-01-29 4:44

If you're doing it in Sepples, the correct answer is to use a rope.

Name: Anonymous 2009-01-29 4:50

>>32
And be sure to allocate slightly less than you think you need.

Name: Anonymous 2009-01-29 8:14

>>31
In the majority case, strcpy is much faster than memcpy.

Name: Anonymous 2009-01-29 8:15

>>31
*(d + al + bl + cl) = 0;
Perhaps you meant [b]'\0'[/b] ?

Name: Anonymous 2009-01-29 8:24

>>35
'\0' is of type int.
0 is of type int.
they are exactly the same.

>>34
strcpy needs to check what each of the bytes is. memcpy doesn't.

Name: Anonymous 2009-01-29 9:02

>>34
In the majority case, the application is spending much more time waiting for I/O than doing work.

Name: Anonymous 2009-01-29 9:21

>>37
What if its a minority case?

Name: Anonymous 2009-01-29 9:40

>>38
Then call it a nigger.

Name: Anonymous 2009-01-29 9:50

>>39
Wouldn't this be racist and xenophobic?

Name: Anonymous 2009-01-29 9:51

>>39
Very funny, your point is void, thank you.

>>36
I prefer '\0', because this way, the person reading the program (me from the future) will instantly understand that this is a string terminator.

Name: Anonymous 2009-01-29 11:29

>>27
I concede that.

With gcc 4.2.1 on my machine, the common subexpressions in >>5 are actually optimized out when -O2 is used:

>>5 took 223 ms
>>11 took 927 ms
>>14 took 236 ms


Declaring the lengths as const rather than volatile allows gcc to make the same optimization, I suspect --

--- test.c.orig 2009-01-29 11:17:03.000000000 -0500
+++ test.c      2009-01-29 11:15:37.000000000 -0500
@@ -44,11 +44,10 @@
 
     then=NOW();
     for(i=0;i<HOWMANY;i++){
-        volatile unsigned int la,lb,lc;
-      
-        la=strlen(a);
-        lb=strlen(b);
-        lc=strlen(c);
+        const unsigned int
+                       la=strlen(a),
+               lb=strlen(b),
+               lc=strlen(c);
       
         d=malloc(la+lb+lc+1);

>>5 took 223 ms
>>11 took 930 ms
>>14 took 224 ms


Interestingly enough, with gcc 3.4.6, volatile produces faster code than const (though significantly slower than 4.2):

volatile:
>>5 took 1141 ms
>>11 took 1309 ms
>>14 took 746 ms

const:
>>5 took 1135 ms
>>11 took 1309 ms
>>14 took 766 ms


The signficant difference between the gcc 4.2 and 3.4 output is because the builtins for string manipulations weren't introduced until the 4.x series. This can be demonstrated by disabling builtins --

gcc34 -fno-builtin -O2 test.c
>>5 took 1446 ms
>>11 took 1434 ms
>>14 took 834 ms

gcc -fno-builtin -O2 test.c
>>5 took 1471 ms
>>11 took 1451 ms
>>14 took 896 ms


Anyway, enough of that. Let's all get back to Haskell and pretend this thread was never posted.

Name: Anonymous 2009-01-29 12:02

I wonder why the title says C++ and everyone wants you to mess with character arrays and strcpy like it was C.

Use the string class.

Name: Anonymous 2009-01-29 12:04

>>43
This was already answered in >>2.

We decided to discuss a topic which is actually meaningful, unlike stupid Sepples bullshit.

Name: Anonymous 2009-01-29 23:01

this thread needs more EXPERT ENTERPRISE JAVA6 EE

Name: Anonymous 2009-01-29 23:26

sprintf

Name: Anonymous 2009-01-29 23:34

char *d = NULL;
asprintf(&d, "%s%s%s", a, b, c);

Name: Anonymous 2009-01-30 0:30

String a = "one";
String b = "two";
String c = "three";

StringBuilder s = new StringBuilder();
s.append(a).append(b).append(c);
String d = s.toString();


I benchmarked this and it's 3% faster than >>42. Enjoy your poor performance, C fans.

Name: Anonymous 2009-01-30 0:47

>>48
Which is negated by the -5000% penalty for starting JVM

Name: Anonymous 2009-01-30 0:50

>>48
hahahaha
oh fuck you java fags. I bet you're some college fag who's never done any real programming. oooh, scared of a little assembly are we? oh no not a pointer! whatever shall we do?
goddamn java fags

Name: Anonymous 2009-01-30 0:59

>>50
hahahaha
oh fuck you c fags. I bet you're some college fag who's never done any real programming. oooh, scared of a little garbage collection are we? oh no not a factory! whatever shall we do?
goddamn c fags

Name: Anonymous 2009-01-30 1:00

>>48
try comparing it to >>31 and >>47.

also, String d = a + b + c; is actually faster than using StringBuilder in this case because the compiler is smart enough to replace a + b + c with the actual value.

Name: Anonymous 2009-01-30 1:06

>>50

Faggot, all object variables in Java are pointers. Must have had a dick in your ass instead of learning useful shit instead of legacy C shit.

>>52

Is maybe right for Java. It would be nice if it had standard byte-code mnemonics. .Net CIL does do that in that case.

Name: Anonymous 2009-01-30 1:14

Is maybe right for Java.
if you're using a compiler that doesn't suck ass, it's smart enough to do that.

Name: Anonymous 2009-01-30 1:17

>>53
if you don't understand the difference between reference and pointer semantics, than I might ask you to leave my beloved /prog/

Name: Anonymous 2009-01-31 20:59

>>55
BITCH GOT TOLD

Name: Anonymous 2011-02-03 0:19

Name: Anonymous 2011-02-04 18:54

Don't change these.
Name: Email:
Entire Thread Thread List