Insert char at string

A

aloha826

Hi,

I would like to insert a char whenever there is a pattern found.

let say the string (mystr) has
New's test's today

so, I would like to insert another apostrophe when encounter an
apostrophe and becomes

New''s test''s today

I try to use strchr and strrchr like below.

if (strchr(mystr, '\''))
*strrchr(mystr, '\'') = '\'\'';

but is the correct to specify \'\' for '' ?

Thanks a lot.

Regards.
 
A

aloha826

I tried with:


void FixString(char * str)
{
char * pch;
pch=strchr(str,'\'');
while (pch!=NULL)
{
str_insert(str, "'", pch-str+1);
pch=strchr(pch+1,'\'');
}




}

char *str_insert(char *dest,const char *substr, int pos)
{
int len1,len2;
ASSERT(pos >= 0 && 0 != dest && 0 != substr);
if ((len1=strlen(dest)) <= pos) strcpy(dest+len1,substr);
else
{
len2 = strlen(substr);
memmove(dest+pos+len2,dest+pos,len1-pos+1);
memcpy(dest+pos,substr,len2);
}
return dest;
}


It can replace the first occurance of "'", but the line:
pch=strchr(pch+1,'\'');
will give problem.

If I have only one "'" in a string, then it is fine,
New's tests today

but if I have more than "'",
New's test's today
the program will terminate

Do you know why ?

Regards.
 
B

Barry Schwarz

I tried with:

You need to show us how you call this function.
void FixString(char * str)
{
char * pch;
pch=strchr(str,'\'');
while (pch!=NULL)
{
str_insert(str, "'", pch-str+1);
pch=strchr(pch+1,'\'');
}




}

char *str_insert(char *dest,const char *substr, int pos)
{
int len1,len2;
ASSERT(pos >= 0 && 0 != dest && 0 != substr);

Why do you think pos == 0 is valid?
if ((len1=strlen(dest)) <= pos) strcpy(dest+len1,substr);

If len1 == pos, then strcpy will overlay the terminating '\0' and you
will have a new longer string. If len1 < pos, strcpy will deposit the
new string after the terminating '\0' and the string will be
unchanged.
else
{
len2 = strlen(substr);
memmove(dest+pos+len2,dest+pos,len1-pos+1);
memcpy(dest+pos,substr,len2);
}
return dest;
}


It can replace the first occurance of "'", but the line:
pch=strchr(pch+1,'\'');
will give problem.

How about telling us what you think the problem is.
If I have only one "'" in a string, then it is fine,
New's tests today

but if I have more than "'",
New's test's today
the program will terminate

Have you run it through a debugger?
 
I

Ike Naar

Why do you think pos == 0 is valid?

Why do you think it is not?

char buf[20] = "fox";
str_insert(buf, "brown ", 0);
str_insert(buf, "quick ", 0);
str_insert(buf, "the ", 0);
/* buf contains "the quick brown fox" */
 
I

Ike Naar

I tried with:


void FixString(char * str)
{
char * pch;
pch=strchr(str,'\'');
while (pch!=NULL)
{
str_insert(str, "'", pch-str+1);
pch=strchr(pch+1,'\'');
}
}

[snip]

It can replace the first occurance of "'", but the line:
pch=strchr(pch+1,'\'');
will give problem.

If I have only one "'" in a string, then it is fine,
New's tests today

but if I have more than "'",
New's test's today
the program will terminate

You mean, the program will *not* terminate.
Do you know why ?

You have an infinite loop.

char str[100] = "let's try";
char * pch;
pch=strchr(str,'\''); /* pch = str+3 */
while (pch!=NULL)
{
str_insert(str, "'", pch-str+1);
pch=strchr(pch+1,'\'');
}

In the first iteration you call str_insert(str, "'", 4),
i.e. a quote is inserted before the 's' in "let's try",
and str becomes "let''s try".
Then pch is updated, and points to str+4.
In the next iteration you call str_insert(str, "'", 5),
str becomes "let'''s try" and pch is set to str+5.
In the next iteration you call str_insert(str, "'", 6),
str becomes "let''''s try" and pch is set to str+6.
And so on.
 
W

woo

I tried with:

void FixString(char * str)
{
  char * pch;
  pch=strchr(str,'\'');
  while (pch!=NULL)
  {


Hi,
I found this
"The strchr() function shall locate the FIRST occurrence of c
(converted to a char) in the string pointed to by s."

hope this might help
 
R

Richard

I tried with:


void FixString(char * str)
{
char * pch;
pch=strchr(str,'\'');
while (pch!=NULL)
{
str_insert(str, "'", pch-str+1);
pch=strchr(pch+1,'\'');
}




}

char *str_insert(char *dest,const char *substr, int pos)
{
int len1,len2;
ASSERT(pos >= 0 && 0 != dest && 0 != substr);
if ((len1=strlen(dest)) <= pos) strcpy(dest+len1,substr);
else
{
len2 = strlen(substr);
memmove(dest+pos+len2,dest+pos,len1-pos+1);
memcpy(dest+pos,substr,len2);
}
return dest;
}


It can replace the first occurance of "'", but the line:
pch=strchr(pch+1,'\'');
will give problem.

If I have only one "'" in a string, then it is fine,
New's tests today

but if I have more than "'",
New's test's today
the program will terminate

Do you know why ?


Did you run it in a debugger and catch the exception?

Try it. Opinion is divided. I and most of the real world use debuggers
all the time to enable their facilities to help us and make our
development time more productive. In .c.l.c a bunch of show offs believe
that debugging takes more time than "doing it right the first time". Of
course,, few people are able to "do it right the first time" which is
why famous developers like Richard Stallman developed things like gdb.

Get some graph paper. Write out a string. Draw your pointers. Step
through.
 
B

Barry Schwarz

Why do you think it is not?

Because the only call to str_insert in the OP's code computed pos as
pointer_1 - pointer_2 + 1 and the pointer arithmetic was guaranteed to
produce a non-negative value which precludes pos from ever being 0.
 
P

Phil Carmody

Barry Schwarz said:
Because the only call to str_insert in the OP's code computed pos as
pointer_1 - pointer_2 + 1 and the pointer arithmetic was guaranteed to
produce a non-negative value which precludes pos from ever being 0.

If a single example client is how you think a function interface and
its preconditions are defined, then, erm, hmmm, I can't finish this
sentence without being at least in part insulting.

If, instead of doubling the "'" to "''", the client had needed to
escape it to "\'" instead, what do you think the value of the
pos parameter might have been when trying to process the string
"'foo'"?

Phil
 
I

Ike Naar

Because the only call to str_insert in the OP's code computed pos as
pointer_1 - pointer_2 + 1 and the pointer arithmetic was guaranteed to
produce a non-negative value which precludes pos from ever being 0.

Even for strictly positive values of pos, pos >= 0 is a valid assertion.
 
C

Chris M. Thomasson

Hi,

I would like to insert a char whenever there is a pattern found.

let say the string (mystr) has
New's test's today

so, I would like to insert another apostrophe when encounter an
apostrophe and becomes

New''s test''s today

I try to use strchr and strrchr like below.

if (strchr(mystr, '\''))
*strrchr(mystr, '\'') = '\'\'';

but is the correct to specify \'\' for '' ?

Thanks a lot.

Does this do what you want?
_________________________________________________________________
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>


static char*
dynstrfindcat(
char* const buf,
char const* const cmp,
char const* const nbuf
) {
char* pos = buf;
size_t const buf_size = strlen(buf);
size_t const nbuf_size = strlen(nbuf);
size_t const cmp_size = strlen(cmp);
size_t new_size = buf_size;

if (buf_size && cmp_size && nbuf_size) {
while ((pos = strstr(pos, cmp))) {
new_size += nbuf_size;
pos += cmp_size;
}

if (new_size > buf_size) {
char* const new_buf = realloc(buf, new_size + 1);

new_buf[new_size] = '\0';
pos = new_buf;

while ((pos = strstr(pos, cmp))) {
pos += cmp_size;
memmove(pos + nbuf_size, pos,
new_size - ((pos + nbuf_size) - new_buf));
memcpy(pos, nbuf, nbuf_size);
pos += nbuf_size;
}

return new_buf;
}
}

return buf;
}


#define BUF "-1-1-1-1"


int main() {
char* buf = malloc(sizeof(BUF));

if (buf) {
buf[0] = '\0';
strcpy(buf, BUF);
printf("origin (%p): %s\n", (void*)buf, buf);

buf = dynstrfindcat(buf, "1", "2");
printf("mutated: (%p): %s\n", (void*)buf, buf);

buf = dynstrfindcat(buf, "2", "4");
printf("mutated: (%p): %s\n", (void*)buf, buf);

buf = dynstrfindcat(buf, "24", "56");
printf("mutated: (%p): %s\n", (void*)buf, buf);

buf = dynstrfindcat(buf, "2", "3");
printf("mutated: (%p): %s\n", (void*)buf, buf);

buf = dynstrfindcat(buf, "6", "789");
printf("mutated: (%p): %s\n", (void*)buf, buf);

buf = dynstrfindcat(buf, "-", "0");
printf("mutated: (%p): %s\n", (void*)buf, buf);

buf = realloc(buf, sizeof("New's test's today"));
buf[sizeof("New's test's today")] = '\0';

strcpy(buf, "New's test's today");
printf("\n\n\norigin: (%p): %s\n", (void*)buf, buf);
buf = dynstrfindcat(buf, "'", "'");
printf("mutated: (%p): %s\n", (void*)buf, buf);

free(buf);
}

return 0;
}
_________________________________________________________________




This is not optimized in any way, shape or form. I also quickly typed this
in, so there may be a typo. It seems to work... ;^)
 
C

Chris M. Thomasson

Of course, there was a bug in the initial version! I did not check the
return value of realloc for NULL!!! ARGH!




static char*
dynstrfindcat(
char* const buf,
char const* const cmp,
char const* const nbuf
) {
char* pos = buf;
size_t const buf_size = strlen(buf);
size_t const nbuf_size = strlen(nbuf);
size_t const cmp_size = strlen(cmp);
size_t new_size = buf_size;

if (buf_size && cmp_size && nbuf_size) {
while ((pos = strstr(pos, cmp))) {
new_size += nbuf_size;
pos += cmp_size;
}

if (new_size > buf_size) {
char* const new_buf = realloc(buf, new_size + 1);

if (new_buf) {
new_buf[new_size] = '\0';
pos = new_buf;

while ((pos = strstr(pos, cmp))) {
pos += cmp_size;
memmove(pos + nbuf_size, pos,
new_size - ((pos + nbuf_size) - new_buf));
memcpy(pos, nbuf, nbuf_size);
pos += nbuf_size;
}

return new_buf;
}
}
}

return buf;
}



Can you notice any more bugs? lol...

;^)
 
C

Chris M. Thomasson

Chris M. Thomasson said:
Hi,

I would like to insert a char whenever there is a pattern found.

let say the string (mystr) has
New's test's today

so, I would like to insert another apostrophe when encounter an
apostrophe and becomes

New''s test''s today

I try to use strchr and strrchr like below.

if (strchr(mystr, '\''))
*strrchr(mystr, '\'') = '\'\'';

but is the correct to specify \'\' for '' ?

Thanks a lot.

Does this do what you want?
_________________________________________________________________
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>


static char*
dynstrfindcat(
char* const buf,
char const* const cmp,
char const* const nbuf
) {
[...]
}


#define BUF "-1-1-1-1"


int main() {
char* buf = malloc(sizeof(BUF));

if (buf) {
buf[0] = '\0';
strcpy(buf, BUF);
[...];

buf = realloc(buf, sizeof("New's test's today"));
buf[sizeof("New's test's today")] = '\0';
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Hummm.... That should probably be:


buf[sizeof("New's test's today") - 1] = '\0';


Where are the pendants when you need them! Just kidding.


:^D
 

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,780
Messages
2,569,608
Members
45,250
Latest member
Charlesreero

Latest Threads

Top