Sasha
Sasha

Reputation:

sprintf and char [] vs. string

I need to pass const char * to a function. Before I pass it, I usually need to build it from some variables. I can never decide which approach is more elegant, and overall better:

Cons of using an array: May not fit the entire text.
Pro: Fast.

Cons of using a string: I don't need to worry about memory management, easy to build. Pro: Slow.

My second question is: How do you usually build a complete string from other variable strings?

Upvotes: 1

Views: 3247

Answers (7)

qrdl
qrdl

Reputation: 35008

You didn't mention your platform, but in case you use glibc as your standard library, there is GNU extension - asprintf(), that automatically allocate string big enough.

See man asprintf for details.

More universal approach - first call fprintf() to unused stream just to get the returned length, then allocate the string and print to it, like this:

FILE *stream = tmpfile();
char *string;

string = malloc(fprintf(stream, format, param)+1);
sprintf(string, format, param);

Upvotes: -1

Imagist
Imagist

Reputation: 18534

Repeat the following to yourself three times every morning when you wake up and three times every night before you go to bed:

"Premature optimization is the root of all evil." - Knuth

In other words, go with the safe, idiomatic C++ way. Speed should be fixed when (and if) it becomes an issue, not before, ESPECIALLY if fixing it before makes your code more error-prone.

As for your second question: look up ropes.

Upvotes: -1

Michael Kristofik
Michael Kristofik

Reputation: 35218

When it comes to C++ and elegance, I tend to follow two rules:

  1. Say what you mean.
  2. Profile first, optimize later.

You're talking about concatenating strings here, so this is the code that comes to mind:

std::string s = s1 + s2 + s3 + s4;
foo(s.c_str());

To "say what you mean," I reach for operator +. Using std::stringstream (a stream of strings) is pretty good too, but I don't immediately go for another #include just to concatenate strings. It's a matter of personal preference I guess. I definitely don't think of building up a raw char array by hand.

In terms of performance, my guess is that operator + is probably the slowest method of putting the strings together. But even a slow method might be fast enough for your purposes.

Upvotes: 2

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507433

This really sounds like a case for Herb Sutter's excellent article The String Formatters of Manor Farm.

For the record: I myself use std::ostringstream, build the string up and pass oss.str().c_str().

Upvotes: 10

Kristopher Johnson
Kristopher Johnson

Reputation: 82565

I almost always use string and stringstream, due to the easier memory management. sprintf and other old-fashioned-C library calls are just too error-prone.

The one benefit of sprintf-style functions over stringstream is that it makes it easy to use different format strings at runtime, for internationalization purposes. But you should definitely use snprintf or one of the other "safer" variants of it.

Upvotes: 2

Timo Geusch
Timo Geusch

Reputation: 24351

Unless it's absolutely performance critical, I tend to use a std::stringstream to build up the string from its components and then c_str() the resulting string. This is safe as there isn't really a chance of a buffer overflow this way and usually fast enough.

If the profiler tells me that building up the string is a hot spot then you will have to trade some safety for speed and start using something like sprintf but I'd rather avoid this. Overall I'd use this as a last resort.

Upvotes: 14

Mark Ransom
Mark Ransom

Reputation: 308538

One crash from a too-short buffer will negate all the speed savings you get from sprintf. I'm not convinced it's faster anyway. And even if it is, is the difference significant enough to worry about?

Upvotes: 4

Related Questions