Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > String Concatenation Using Pointers No strcat()

Reply
Thread Tools

String Concatenation Using Pointers No strcat()

 
 
raidvvan@yahoo.com
Guest
Posts: n/a
 
      12-07-2007
Hi there,

I am having a bit of an issue when trying to concatenate strings using
char * pointers.

Here is what I need:

I need to add a list of ID's to a string that is a SQL statement so
that I can end up with:
SELECT DISTINCT Object_ID FROM Object_Interactions WHERE Object_ID IN
('UUID1', 'UUID2') ORDER BY Object_ID ASC;

Here is what I am doing:

struct object_type
{
char *id; /* UUID = 32 chars length */
};

void strappnd(char *dest, char *src)
{
/* appends one string to another */
while (*src != '\0')
*dest++ = *src++;

*dest = '\0';
}

char *buffer = NULL;
char *sql = NULL;
int j = 0;
int buffer_size = 0;
int object_count = 0;

object_count = 2; /* this is actually a calculated value... */

/* I have used malloc() and then assigned a value to object_list[j]-
>id and that was OK */


buffer_size = 32 * object_count + strlen("''") * object_count +
strlen(", ") * (object_count - 1) + 1;

buffer = (char *)malloc(buffer_size * sizeof(char)); /* I know about
pointer casting issue and malloc without stdlib.h but there is too
much code to be changed... */
strcpy(buffer, "");

for (j=0; j<object_count; j++)
{
printf("buffer=%s\n", buffer);

strcat(buffer, "'");
strappnd(buffer, object_list[j]->id);

/* we must not end the sequence with a comma */
if (j < object_count - 1)
strcat(buffer, "', '");
else
strcat(buffer, "'");
}
sql = (char *)malloc((100 + buffer_size + 1) * sizeof(char));
sprintf(sql, "SELECT DISTINCT Object_ID FROM Object_Interactions WHERE
Object_ID IN (%s) ORDER BY Object_ID ASC;", buffer);
free(buffer);

printf("sql=%s\n", sql);

Result:
sql = SELECT DISTINCT Object_ID FROM Object_Interactions WHERE
Object_ID IN (UUID1') ORDER BY Object_ID ASC;

I have been trying and searching for a couple of days for all kinds of
solutions but I can't seem to find anything and I can't make it work.
Basically the question is how to transform a const char * into a char
*. Does simple casting work? Is it safe? What else can I do because
I keep hitting this wall, and I can't use the standard <string.h>
functions because most of them expect a char const * as opposed to
char * in one of the arguments.

I have been looking on the Internet and forums, but for most cases
strcat is being used and seems to be enough.
I found interesting variations of strcat, but they don't seem to work
and I don't have any more time for this. After finding libAPR I even
thought of using it, but I only need one function from this library
and plus the application must be portable on Linux, Mac, Windows...

Any help on how to do string concatenation with char * or how to
convert const char * to char * would be greatly appreciated.

Other than that, C is just great.

Thanks very much.
Ovidiu Anghelidi
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
 
 
 
Mark Bluemel
Guest
Posts: n/a
 
      12-07-2007
(E-Mail Removed) wrote:
> Hi there,
>
> I am having a bit of an issue when trying to concatenate strings using
> char * pointers.


[Snip]

> void strappnd(char *dest, char *src)
> {
> /* appends one string to another */
> while (*src != '\0')
> *dest++ = *src++;
>
> *dest = '\0';
> }


This is strcpy() surely?

> I have been trying and searching for a couple of days for all kinds of
> solutions but I can't seem to find anything and I can't make it work.


Your presentation of the problem is too verbose and ill-formed for me to
make sense of it.

Surely before posting you could have boiled down your problem to a
really simple testcase?

If you simply want to process something like this :-

char *uuids[4] = { "UUID1", "UUID2", "UUID3", "UUID4" };

into

char *all_uuids; /*containing "UUID1, UUID2, UUID3, UUID4" */

What about this :-

#include <stdio.h>
#include <string.h>
int main(void) {
char *uuids[4] = {"UUID1", "UUID2", "UUID3", "UUID4"};
char *all_uuids = malloc(1024); /* arbitrary size
* and needs error check
*/
int i;
for (i = 0; i < 4; i++) {
if (i>0) {
strcat(all_uuids,", ");
}
strcat(all_uuids,uuids[i]);
}
printf("all the uuids are (%s)\n",all_uuids);
}
 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      12-07-2007
(E-Mail Removed) writes:

> I am having a bit of an issue when trying to concatenate strings using
> char * pointers.
>
> Here is what I need:
>
> I need to add a list of ID's to a string that is a SQL statement so
> that I can end up with:
> SELECT DISTINCT Object_ID FROM Object_Interactions WHERE Object_ID IN
> ('UUID1', 'UUID2') ORDER BY Object_ID ASC;
>
> Here is what I am doing:
>
> struct object_type
> {
> char *id; /* UUID = 32 chars length */
> };
>
> void strappnd(char *dest, char *src)
> {
> /* appends one string to another */
> while (*src != '\0')
> *dest++ = *src++;
>
> *dest = '\0';
> }


Basic problem is that you believe the comment not the code. The
above doe snot append. It overwrites.

> char *buffer = NULL;
> char *sql = NULL;
> int j = 0;
> int buffer_size = 0;
> int object_count = 0;
>
> object_count = 2; /* this is actually a calculated value... */
>
> /* I have used malloc() and then assigned a value to object_list[j]-
>>id and that was OK */

>
> buffer_size = 32 * object_count + strlen("''") * object_count +
> strlen(", ") * (object_count - 1) + 1;
>
> buffer = (char *)malloc(buffer_size * sizeof(char)); /* I know about
> pointer casting issue and malloc without stdlib.h but there is too
> much code to be changed... */
> strcpy(buffer, "");
>
> for (j=0; j<object_count; j++)
> {
> printf("buffer=%s\n", buffer);
>
> strcat(buffer, "'");
> strappnd(buffer, object_list[j]->id);


If you had just gone on to use strcat it would have worked.

> /* we must not end the sequence with a comma */
> if (j < object_count - 1)
> strcat(buffer, "', '");
> else
> strcat(buffer, "'");
> }
> sql = (char *)malloc((100 + buffer_size + 1) * sizeof(char));
> sprintf(sql, "SELECT DISTINCT Object_ID FROM Object_Interactions WHERE
> Object_ID IN (%s) ORDER BY Object_ID ASC;", buffer);
> free(buffer);
>
> printf("sql=%s\n", sql);
>
> Result:
> sql = SELECT DISTINCT Object_ID FROM Object_Interactions WHERE
> Object_ID IN (UUID1') ORDER BY Object_ID ASC;
>
> I have been trying and searching for a couple of days for all kinds of
> solutions but I can't seem to find anything and I can't make it work.
> Basically the question is how to transform a const char * into a char
> *. Does simple casting work?


Yes, but...

> Is it safe?


No.

> What else can I do because
> I keep hitting this wall, and I can't use the standard <string.h>
> functions because most of them expect a char const * as opposed to
> char * in one of the arguments.


strcat has a const string argument only as the source. Personally, I
would check the UUID lengths before adding them, and advance a buffer
pointer as I went. You'd get some added assurance that you won't
overflow your buffer and you can use strcpy rather than strcat.

> Any help on how to do string concatenation with char * or how to
> convert const char * to char * would be greatly appreciated.


If you need to, something has probably gone very wrong.

--
Ben.
 
Reply With Quote
 
raidvvan@yahoo.com
Guest
Posts: n/a
 
      12-07-2007
On Dec 7, 10:54 am, Mark Bluemel <(E-Mail Removed)> wrote:
> This is strcpy() surely?


Yes, I can see that now.

> Your presentation of the problem is too verbose


Sorry about that. And to think that initially I wanted to post another
2 or 3 pages of code.

Thanks for the reply.
 
Reply With Quote
 
raidvvan@yahoo.com
Guest
Posts: n/a
 
      12-07-2007
On Dec 7, 11:10 am, Ben Bacarisse <(E-Mail Removed)> wrote:

> If you had just gone on to use strcat it would have worked.


I tried that before, but I got segmentation fault and that's why I
thought of replacing it. I will try again with the checking.

> If you need to, something has probably gone very wrong.


This is great. I kept thinking that this is the way to go.

Thanks a lot,
Ovidiu
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      12-07-2007
Mark Bluemel <(E-Mail Removed)> writes:
[...]
> What about this :-
>
> #include <stdio.h>
> #include <string.h>
> int main(void) {
> char *uuids[4] = {"UUID1", "UUID2", "UUID3", "UUID4"};
> char *all_uuids = malloc(1024); /* arbitrary size
> * and needs error check
> */
> int i;
> for (i = 0; i < 4; i++) {
> if (i>0) {
> strcat(all_uuids,", ");
> }
> strcat(all_uuids,uuids[i]);
> }
> printf("all the uuids are (%s)\n",all_uuids);
> }


One problem with that is that strcat() has to scan the target string
each time before appending the new string. For a small number of
short strings like you have here, it's probably not a big deal, but
it's an O(N**2) algorithm for something that can easily be done in
O(N).

An improvement would be to use strcpy() rather than strcat(), and
update a pointer to point to the end of the string after each step.
This still does some unnecessary scanning, but at least it doesn't
re-scan the same string repeatedly.

If you have a fixed number of strings to append, you might consider
sprintf() (though the overhead of processing the format string
might be excessive):
sprintf(all_uuids, "%s, %s, %s, %s",
uuids[0], uuids[1], uuids[2], uuids[3]);

Or you can write your own routine that keeps track of the end of the
string as it goes along.

--
Keith Thompson (The_Other_Keith) <(E-Mail Removed)>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Default User
Guest
Posts: n/a
 
      12-07-2007
(E-Mail Removed) wrote:

> On Dec 7, 11:10 am, Ben Bacarisse <(E-Mail Removed)> wrote:
>
> > If you had just gone on to use strcat it would have worked.

>
> I tried that before, but I got segmentation fault and that's why I
> thought of replacing it. I will try again with the checking.


That's the stage at which you should have come to us. You should know
that generally speaking the standard library function WORK. So if you
are having a problem, it's likely a simple case of misuse.

Go back and post that code. We'll fix it and you'll be better off all
around.




Brian
 
Reply With Quote
 
raidvvan@yahoo.com
Guest
Posts: n/a
 
      12-07-2007
On Dec 7, 2:58 pm, Keith Thompson <(E-Mail Removed)> wrote:

> One problem with that is that strcat() has to scan the target string
> each time before appending the new string. For a small number of
> short strings like you have here, it's probably not a big deal, but
> it's an O(N**2) algorithm for something that can easily be done in
> O(N).


strcat() is good enough for what I am doing now

> If you have a fixed number of strings to append, you might consider
> sprintf() (though the overhead of processing the format string


I don't know how many UUID's are in the array so that's why I am
appending.

Thank you.

 
Reply With Quote
 
raidvvan@yahoo.com
Guest
Posts: n/a
 
      12-07-2007
On Dec 7, 3:04 pm, "Default User" <(E-Mail Removed)> wrote:

> That's the stage at which you should have come to us. You should know
> that generally speaking the standard library function WORK. So if you
> are having a problem, it's likely a simple case of misuse.


I have got only a few months of C so if there is something wrong, I
always assume I need to expand my view and search for something else.
strcpy and strcat expect const char *, and because I am using char * I
haven't seen too many examples in which you can just pass the char *
pointer to the function. Most examples deal with char []. Plus I don't
feel like wasting someone's else time without doing even a shabby
homework.

I can't make any changes right now. I will have to do it tomorrow.

Thank you very much.

 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      12-07-2007
(E-Mail Removed) said:

> On Dec 7, 3:04 pm, "Default User" <(E-Mail Removed)> wrote:
>
>> That's the stage at which you should have come to us. You should know
>> that generally speaking the standard library function WORK. So if you
>> are having a problem, it's likely a simple case of misuse.

>
> I have got only a few months of C so if there is something wrong, I
> always assume I need to expand my view and search for something else.
> strcpy and strcat expect const char *,


For the *source*, not the target. And the const is effectively a promise
that strcpy and strcat won't change the data you're copying *from* in the
process of copying that data to the target.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
String concatenation vs. string formatting Andrew Berg Python 13 07-10-2011 11:24 PM
pointers, pointers, pointers... cerr C Programming 12 04-07-2011 11:17 PM
Re: Using os.system() and string concatenation Wayne Witzel III Python 2 10-17-2004 06:24 PM
Using os.system() and string concatenation Wayne Witzel III Python 1 10-12-2004 07:29 PM
what's the difference between VHDL 93 CONCATENATION and VHDL 87 CONCATENATION? walala VHDL 3 09-18-2003 04:17 AM



Advertisments