0

I have a code like following -

Value = "Current &HT"; //this is value void StringSet(const char * Value) { const char *Chk = NULL; Chk = strpbrk(Value,"&"); if(Chk != NULL) { strncpy(const_cast<char *> (Chk),"&amp",4) } } 

In above code I would like to replace "&" from Value with "&amp.It works fine if I have "&" single character but in current case strpbrk() return "&HT"and in below strncpy whole "&HT"is replaced.

Now I would like to know methods by which I can only replace a single character from a string.

2
  • 3
    Why would you not use std::string for this? It has a replace function. Commented Mar 26, 2013 at 6:28
  • I want to use that but as I am working on a already defined program I am under some restriction to not use std::string. Commented Mar 26, 2013 at 6:31

4 Answers 4

2

You cannot replace one character in a C style string with several because you cannot know in a C style string how much room you have available to add new characters. You can only do this by allocating a new string and copying the old string to the new. Something like this

char* StringSet(const char* value) { // calculate how many bytes we need size_t bytes = strlen(value) + 1; for (const char* p = value; *p; ++p) if (*p == '&') bytes += 3; // allocate the new string char* new_value = new char[bytes]; // copy the old to the new and replace any & with &amp char* q = new_value; for (const char* p = value; *p; ++p) { *q = *p; ++q; if (*p == '&') { memcpy(q, "amp", 3); q += 3; } } *q = '\0'; return new_value; } 

But this is terrible code. You really should use std::string.

Sign up to request clarification or add additional context in comments.

3 Comments

If you're doing all the work to calculate the final string size and iterate copying, you can very easily fix value in-place (using a backward iteration), which seems to be the intent of the poster's code. Of course, that has buffer overrun potential. +1 for "You really should use std::string".
@TonyD Well that was my point when I said you don't know how much room you have available. Plus there is the issue of calling this function with a string literal.
very good points, in light of which the compromises you've selected look great. Cheers.
1

I think you need some temp array to hold string past & and then replace & in original string and append temp array to original. Here is the above code modified, I believe you can use strstr instead of strchr it accepts char* as second argument.

void StringSet(char * Value) { char *Chk = NULL,*ptr = NULL; Chk = strchr(Value,'&'); if(Chk != NULL) { ptr = Chk + 1; char* p = (char*)malloc(sizeof(char) * strlen(ptr)); strcpy(p,ptr); Value[Chk-Value] = '\0'; strcat(Value,"&amp"); strcat(Value,p); free(p); } } 

Thanks Niraj Rathi

Comments

0

You should not modify a constant string, and certainly can't modify a string literal. Although it is much much better to use a std::string instead of dealing with resource management yourself, one way is to allocate a new c-style string and return a pointer to it:

char *StringSet(const char *Value) { char buffer[256]; for (char *p = (char*)Value, *t = buffer; p[0] != 0; p++, t++) { t[0] = p[0]; if (p[0] == '&') { t[1] = 'a'; t[2] = 'm'; t[3] = 'p'; t += 3; } t[1] = 0; } char *t = new char[strlen(buffer)+1]; strcpy(t, buffer); return t; } 

Comments

0
string str="Current &HT"; str.replace(str.find('&'),1,"&amp"); 

1 Comment

"I am working on a already defined program I am under some restriction to not use std::string"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.