How to replace parts of a string with something else

M

Melroy

sorry for the naive question, as I am new to C. But is there a simple
and elegant way to replce parts of a string (if one knows the start
position and number of characters)
with something else?
in other words, if
string1 = "Hello World"
I want to replace the 3rd and 4th characters (In this "ll") with "pp"
so that string1 = "Hepp World"
How does one do that? Is there I could not find it in the C FAQ on
the web.
(There is a way to extract parts of a string into another one which
is addressed in
http://c-faq.com/charstring/substr.html)
but not what I am trying to do (which is sort of reverse that)
Thanks very much
 
V

virtual

If the original phrase is the same length as the replacement phrase
then it's pretty easy, just use "strchr" to find the first character
and then maybe use strcmp to find the whole phrase, something like:

(Unchecked code thrown together)

char const *const pnull = str + strlen(str);

char const before[] = "dog";
char const after[] = "cat";

assert(sizeof before == sizeof after);

char *p = str;

for (;;)
{
if (!*p)
return;

p = strchr(p,before[0]);

if (!p)
return;

if (pnull-p < sizeof before)
return;

char const temp = p[sizeof before];

p[sizeof before] = '\0';

if (!strncmp(p,before))
strcpy(p,after);

p[sizeof before] = temp;

p += sizeof before;
}

If the original and replacement string are of different length, then
you need to play around with memmove. By the way there's already
string libraries written for C if you want to spend your time working
on other aspects of your program.
 
A

Andy

sorry for the naive question, as I am new to C. But is there a simple
and elegant way to replce parts of a string (if one knows the start
position and number of characters)
with something else?
in other words, if
string1 = "Hello World"
I want to replace the 3rd and 4th characters (In this "ll") with "pp"
so that string1 = "Hepp World"
How does one do that? Is there I could not find it in the C FAQ on
the web.
(There is a way to extract parts of a string into another one which
is addressed in
http://c-faq.com/charstring/substr.html)
but not what I am trying to do (which is sort of reverse that)
Thanks very much

I:\c16>type d11.c
#include <stdio.h>
#include <string.h>

int main(void) {
char string[] = "Hello World";

printf("%s\n", string);
strncpy(string + 2, "pp", 2);
printf("%s\n", string);

return 0;
}

I:\c16>tcc d11.c
Turbo C Version 2.01 Copyright (c) 1987, 1988 Borland International
d11.c:
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland
International

Available memory 391068

I:\c16>d11
Hello World
Heppo World

I:\c16>
 
J

jaysome

Melroy said:
sorry for the naive question, as I am new to C. But is there a simple
and elegant way to replce parts of a string (if one knows the start
position and number of characters)
with something else?
in other words, if
string1 = "Hello World"
I want to replace the 3rd and 4th characters (In this "ll") with "pp"
so that string1 = "Hepp World"

size_t start = 2;
char replacementstring[] = "pp";
^^^^^^^^^^^^^^^^^
A truly horrendous name for a variable. At first I thought it stood
for "Replace me NT string" (perhaps some type of string operation
performed on Windows NT).

Underscores are cheap in this day and age--and the benefit they
provide are enormous.
size_t number_to_replace = 2;

char mystring[] = "Hello World";
memcpy(mystring + start, replacement_string, number_to_replace);
^^^^^^^^^^^^^^^^^^
Outstanding name for a variable!

On my crystal ball compiler this compiles with no errors, but
unfortunately on all of my real-world compilers, there's an error,
e.g.:

error C2065: 'replacement_string' : undeclared identifier

s/replacementstring/replacement_string/g
 
L

lovecreatesbeauty

sorry for the naive question, as I am new to C.  But is there a simple
and elegant way to replce parts of a string (if one knows the start
position and number of characters)
with something else?
in other words, if
string1 = "Hello World"
I want to replace the 3rd and 4th characters (In this "ll") with "pp"
so that string1 = "Hepp World"
How does one do that? Is there  I could not find it in the C FAQ on
the web.
(There is a way to extract  parts of a string into another one which
is addressed inhttp://c-faq.com/charstring/substr.html)
but not what I am trying to do (which is sort of reverse that)

My version of a user function to replace a sub string. Comments are
welcome.

/* a.c */

#include <stdlib.h>
#include <string.h>

/*
* Replace string pointed to by sub with rep in str.
*/
char *strrep(char *str, const char *sub, const char *rep)
{
const char *p1, *p5;
char *p2, *p3, *p4;
size_t nstr = strlen(str), nsub= strlen(sub);

p1 = str + nstr;
for (p2 = str; p2 = strstr(p2, sub); p2++){
p3 = p2;
p4 = p2 + nsub;
while (*p3++ = *p4++);
p3--, p4--;
p5 = rep;
for (; p3 != p1 && *p5; p2++, p3++, p5++){
for (p4 = p3; p4 >= p2; p4--)
*(p4 + 1) = *p4;
*++p4 = *p5;
}
}
return str;
}


#include <stddef.h>
#include <stdio.h>

#define LEN 1024
int main(int argc, char *argv[]){
char str[LEN] = {'\0'}, sub[LEN] = {'\0'}, rep[LEN] = {'\0'};

if (argc != 4){
printf("%s\n", "Usage: a.out <str> <sub> <rep>");
strncpy(str, "hello world", sizeof str - 1);
strncpy(sub, "hel", sizeof sub - 1);
strncpy(rep, "HEL", sizeof rep - 1);
} else {
strncpy(str, argv[1], sizeof str - 1);
strncpy(sub, argv[2], sizeof sub - 1);
strncpy(rep, argv[3], sizeof rep - 1);
}
printf("%s\n", str);
strrep(str, sub, rep);
printf("%s\n", str);
return EXIT_SUCCESS;
}
 
K

Keith Thompson

My version of a user function to replace a sub string. Comments are
welcome.

/* a.c */

#include <stdlib.h>

You don't use anything from said:
#include <string.h>

/*
* Replace string pointed to by sub with rep in str.
*/
char *strrep(char *str, const char *sub, const char *rep)

Names starting with "str" and a lowercase letter are reserved.
str_rep would be ok.
{
const char *p1, *p5;
char *p2, *p3, *p4;

These names make it difficult to follow what the code is doing.
size_t nstr = strlen(str), nsub= strlen(sub);

p1 = str + nstr;
for (p2 = str; p2 = strstr(p2, sub); p2++){

It seems odd to call strstr() in the condition of a for loop. Perhaps
it makes sense here; I haven't studied this part of the code enough to
be sure.
p3 = p2;
p4 = p2 + nsub;
while (*p3++ = *p4++);
p3--, p4--;
p5 = rep;
for (; p3 != p1 && *p5; p2++, p3++, p5++){
for (p4 = p3; p4 >= p2; p4--)
*(p4 + 1) = *p4;
*++p4 = *p5;
}
}
return str;
}


#include <stddef.h>
#include <stdio.h>

#define LEN 1024
int main(int argc, char *argv[]){
char str[LEN] = {'\0'}, sub[LEN] = {'\0'}, rep[LEN] = {'\0'};

I'd put these declarations on separate lines. I'd also use "" rather
than {'\0'} as the initializer.
if (argc != 4){
printf("%s\n", "Usage: a.out <str> <sub> <rep>");
strncpy(str, "hello world", sizeof str - 1);
strncpy(sub, "hel", sizeof sub - 1);
strncpy(rep, "HEL", sizeof rep - 1);
} else {
strncpy(str, argv[1], sizeof str - 1);
strncpy(sub, argv[2], sizeof sub - 1);
strncpy(rep, argv[3], sizeof rep - 1);
}

strncpy is very rarely the right answer. If the source string is
short, it wastes time filling the rest of the target with null
characters. If it's too long, it leave the target without a '\0'
terminator. In this case, if argv[1] is too long to store in a
1024-byte array, then str won't be properly terminated, and you'll
invoke undefined behavior.

Just use strcpy(). If you want to check for overly long inputs, check
the input length and print an error message if necessary.
 
D

David Thompson

If the original phrase is the same length as the replacement phrase
then it's pretty easy, just use "strchr" to find the first character
and then maybe use strcmp to find the whole phrase, something like:

(Unchecked code thrown together)

char const *const pnull = str + strlen(str);

char const before[] = "dog";
char const after[] = "cat";

assert(sizeof before == sizeof after);

char *p = str;

for (;;)
{
if (!*p)
return;

p = strchr(p,before[0]);

if (!p)
return;

if (pnull-p < sizeof before)
return;
You don't need the !*p exit, as then strchr will (always) return null;
so you can get all into one loop condition. Need sizeof before -1 or
strlen(before), or the < should be <=; but see below.
char const temp = p[sizeof before];

p[sizeof before] = '\0';

if (!strncmp(p,before))
strcpy(p,after);

p[sizeof before] = temp;
That strncmp call is wrong (needs third argument); if you use strncmp
correctly, and memcpy instead of strcpy, you don't need the save and
restore logic (and temp). And then you don't need the enough-room test
above either; too-short data will just mismatch.
p += sizeof before;

If you want to do all matches, you should advance sizeof before -1 (or
strlen) only if you matched and replaced, otherwise you should only
advance 1. Unless you do Boyer-Moore style optimization, and even then
it will often be less than the full length. If you don't want to do
all matches, you don't need the skip logic of the loop at all.
 

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,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top