C Style Strings

S

scroopy

Hi,

I've always used std::string but I'm having to use a 3rd party library
that returns const char*s. Given:

char* pString1 = "Blah ";
const char* pString2 = "Blah Blah";

How do I append the contents of pString2 to pString? (giving "Blah
Blah Blah")

I looked at strcat but that crashes with an unhandled exception.

Thanks
 
J

jpalecek

scroopy said:
Hi,

I've always used std::string but I'm having to use a 3rd party library
that returns const char*s. Given:

char* pString1 = "Blah ";
const char* pString2 = "Blah Blah";

How do I append the contents of pString2 to pString? (giving "Blah
Blah Blah")

I looked at strcat but that crashes with an unhandled exception.

That's easy, do it the C way:

char* result=new char[strlen(s1)+strlen(s2)+1];
strcpy(result,s1);
strcat(result,s2);

Regards
Jiri Palecek
 
K

Kai-Uwe Bux

scroopy said:
Hi,

I've always used std::string but I'm having to use a 3rd party library
that returns const char*s. Given:

char* pString1 = "Blah ";
const char* pString2 = "Blah Blah";

How do I append the contents of pString2 to pString? (giving "Blah
Blah Blah")

a) Keep using std::string for your own stuff. The std::string class has
methods that allow you to interact with C-style string interfaces of
libraries.

b) Note that in your example above, pString1 is initialized to a const
string. Any attempt to modify that string would be undefined behavior. The
danger lies in not declaring pString1 as a char const *.

c) You could do:

#include <string>
#include <algorithm>

char * strdup ( std::string str ) {
char * result = new char [ str.length() +1 ];
std::copy( str.begin(), str.end(), result );
result[ str.length() ] = 0;
return ( result );
}

int main ( void ) {
char * pString1 = "Blah ";
char const * pString2 = "Blah Blah";
pString1 = strdup( std::string( pString1 ).append( pString2 ) );
}


However, I would prefer to use std::string for my own stuff:

#include <string>

int main ( void ) {
std::string pString1 = "Blah "; // rhs returned by some library
std::string pString2 = "Blah Blah"; // rhs returned by some library
pString1.append( pString2 );
}


Best

Kai-Uwe Bux
 
R

Roland Pibinger

I've always used std::string but I'm having to use a 3rd party library
that returns const char*s.

First you need to find out if you 'own' the returned string, i.e. if
you must free (maybe delete) the returned char*. Good C libraries
usually don't require the user to call free.
Given:

char* pString1 = "Blah ";
const char* pString2 = "Blah Blah";

How do I append the contents of pString2 to pString? (giving "Blah
Blah Blah")

You can append a const char* to a std::string:

string myString = "Blah ";
const char* s = myLibFunc (...);
if (s) {
myString += s; // or myString.append(s);
}
// free (s); // if it's a bad lib

Best wishes,
Roland Pibinger
 
K

kwikius

scroopy said:
Hi,

I've always used std::string but I'm having to use a 3rd party library
that returns const char*s. Given:

char* pString1 = "Blah ";
const char* pString2 = "Blah Blah";

How do I append the contents of pString2 to pString? (giving "Blah
Blah Blah")

#include <malloc.h>
#include <cstring>

char* concat(const char * str1, const char* str2)
{
char * result = (char*) malloc(strlen( str1) + strlen (str2) + 1);
if( result != NULL){
strcpy(result,str1);
strcat(result, str2);
}
return result;
}

#include <iostream>
#include <string>

char* pString1 = "Blah ";
const char* pString2 = "Blah Blah";


int main()
{
// C-style
char* str = concat(pString1,pString2);
if(str != NULL){
std::cout << str <<'\n';
free(str);
}

// C++ style
std::string str1=std::string(pString1) + pString2;
std::cout << str1 <<'\n';
}

I'm not sure if that is the optimal C method. Its interesting to note
how much better the C++ version is though!

regards
Andy Little
 
R

Richard Bos

kwikius said:
#include <malloc.h>
#include <cstring>

This is not C...
char* concat(const char * str1, const char* str2)
{
char * result = (char*) malloc(strlen( str1) + strlen (str2) + 1);

....and this is the wrong way to do this in C. And, really, also in C++:
use new.

So don't cross-post stuff like that. Follow-ups set.

Richard
 
K

kwikius

Roland said:
First you need to find out if you 'own' the returned string, i.e. if
you must free (maybe delete) the returned char*. Good C libraries
usually don't require the user to call free.

Out of interest ... What is a good C library resource management
strategy? ... for example (say) modifying the following example

char* concat(const char * str1, const char* str2)
{
char * result = (char*) malloc(strlen( str1) + strlen (str2) + 1);
if( result != NULL){
strcpy(result,str1);
strcat(result, str2);
}
return result;
}

char* pString1 = "Blah ";
const char* pString2 = "Blah Blah";

int main()
{
char* str = concat(pString1,pString2);
if(str != NULL){
std::cout << str <<'\n';
free(str); // How to avoid this in C-style?
}
}

regards
Andy Little
 
R

Richard Heathfield

Richard Bos said:
This is not C...

....and it's not C++ either, so I'm not sure why you set followups to clc++.

The entire article, in fact (his, not yours), was a classic example of the
kind of thing you get in the Hackitt and Scarper school of programming.
 
K

kwikius

Richard said:
This is not C...


...and this is the wrong way to do this in C.

Out of interest what is the right way? BTW... It would seem to me to
make sense to cross-post this to comp.lang.c as it is somewhat O.T. for
C++. I think It makes sense in terms of a language comparison though,
don't you think?
And, really, also in C++:

hmmm... Touchy arent we? I showed a C++ way in my previous post.

Sure? .. The best way is not to allocate resources the users has to
manage , isnt it?.
So don't cross-post stuff like that. Follow-ups set.

Hmm... Are you sure I wouldnt get a better answer to the how to do it
in C question in a C newsgroup?

regards
Andy Little
 
K

kwikius

Richard said:
Richard Bos said:


...and it's not C++ either, so I'm not sure why you set followups to clc++.

The entire article, in fact (his, not yours), was a classic example of the
kind of thing you get in the Hackitt and Scarper school of programming.

Thats great! Thanks! Its always good to get positive feedback!

regards
Andy Little
 
R

Roland Pibinger

Out of interest ... What is a good C library resource management
strategy? ... for example (say) modifying the following example

char* concat(const char * str1, const char* str2)

This is almost the declaration of strcat, but strcat operates on the
given buffer and doesn't allocate anything. AFAIK, no Standard C
library functions returns anything to be freed.
Your example could be rewritten as:

char* concat (const char * str1, const char* str2, char* result,
size_t resultLen);

The function returns NULL when the 'contract' (string concatenation)
cannot be fulfilled, e.g. because the result-buffer is to small.
resultLen is for additional safety.

Best wishes,
Roland Pibinger
 
K

kwikius

Roland said:
On 1 Jun 2006 01:29:33 -0700, "kwikius"
[...]
Out of interest ... What is a good C library resource management
strategy? ... for example (say) modifying the following example

char* concat(const char * str1, const char* str2)

This is almost the declaration of strcat, but strcat operates on the
given buffer and doesn't allocate anything. AFAIK, no Standard C
library functions returns anything to be freed.
Your example could be rewritten as:

char* concat (const char * str1, const char* str2, char* result,
size_t resultLen);

The function returns NULL when the 'contract' (string concatenation)
cannot be fulfilled, e.g. because the result-buffer is to small.
resultLen is for additional safety.

Thanks for the answer. So the answer to the question of a library
resource management strategy in C is that there isnt one. Everything to
do with resource managment should be done manually by the user, whereas
in C++ it is usual to automate resource management thus dramatically
simplifying life for the user. That would seem to be a clear win for
C++ over C!

regards
Andy Little
 
I

Ian Collins

kwikius said:
Out of interest what is the right way? BTW...

He was probably referring to the cast, which isn't used in C due to
implicit conversion from void*
 
R

Roland Pibinger

So the answer to the question of a library
resource management strategy in C is that there isnt one.

Let the user provide the necessary resources. Actually, IMO, that's a
very good resource management strategy. In C and C++.
Everything to
do with resource managment should be done manually by the user, whereas
in C++ it is usual to automate resource management thus dramatically
simplifying life for the user. That would seem to be a clear win for
C++ over C!

Yes, the C++ advantage stems from RAII.

Best wishes,
Roland Pibinger
 
P

peter koch

Ian Collins skrev:
He was probably referring to the cast, which isn't used in C due to
implicit conversion from void*

To explicitise an implicit conversion does not stop it being C. It just
starts it being C++ as well.

/Peter
 
I

Ian Collins

peter said:
Ian Collins skrev:


To explicitise an implicit conversion does not stop it being C. It just
starts it being C++ as well.
No it doesn't, but try telling that to the folks down the hall, they get
very hot under the collar.

There is a valid reason for not doing explicit casts on function returns
in C, it masks missing headers (not an issue in C++).
 
N

Nick Keighley

kwikius said:
scroopy wrote:

I assume most of the code is C++ and that you have to handle C strings
as well.
I'm facing the same problem (plus a third party string class...). My
approach
was to get rid of the C strings as soon as possible. And only convert
back at
the last minute.

std::string result = std::string(pString1) + pString2;

#include <malloc.h>
not a valid header (in either language)
#include <cstdlib>

or better yet don't use malloc(). Mixing malloc() and new can be hairy.
#include <cstring>

when using C headers decide which sort to use. If you use this you need
to
namespace qualify your C calls.
char* concat(const char * str1, const char* str2)
{
char * result = (char*) malloc(strlen( str1) + strlen (str2) + 1);

std::malloc() or use new or use std::string
if( result != NULL){
strcpy(result,str1);
std::strcpy() etc.
strcat(result, str2);
}
return result;
}

<snip>
 
S

SuperKoko

kwikius said:
Roland said:
On 1 Jun 2006 01:29:33 -0700, "kwikius"
[...]
Out of interest ... What is a good C library resource management
strategy? ... for example (say) modifying the following example

char* concat(const char * str1, const char* str2)

This is almost the declaration of strcat, but strcat operates on the
given buffer and doesn't allocate anything. AFAIK, no Standard C
library functions returns anything to be freed.
Your example could be rewritten as:

char* concat (const char * str1, const char* str2, char* result,
size_t resultLen);

The function returns NULL when the 'contract' (string concatenation)
cannot be fulfilled, e.g. because the result-buffer is to small.
resultLen is for additional safety.

Thanks for the answer. So the answer to the question of a library
resource management strategy in C is that there isnt one. Everything to
do with resource managment should be done manually by the user, whereas
in C++ it is usual to automate resource management thus dramatically
simplifying life for the user. That would seem to be a clear win for
C++ over C!
Even if it is popular in C. Many C libraries use another way:
GString is a good example of a clean C interface:
http://developer.gnome.org/doc/API/glib/glib-strings.html#G-STRING-FREE

Instead of having to call "free", the user must call a library-provided
resource deallocating function.

Using internally, functions which use with the any range of
user-provided memory (or iterators) is a good way to reuse efficiently
code.
However, in C, as in C++, it is good to encapsulate things and to
provide comfortable interfaces.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top