Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / char replace

Author
Message
AlexI
19
Years of Service
User Offline
Joined: 31st Dec 2004
Location: UK
Posted: 3rd Feb 2009 22:39
Hi,
How can I do a whole search & replace on a char*?

Thanks,
Alex

dark coder
22
Years of Service
User Offline
Joined: 6th Oct 2002
Location: Japan
Posted: 3rd Feb 2009 23:06 Edited at: 3rd Feb 2009 23:08
Allocate a buffer large enough for your output string. Then create a loop from 0 to the input string length - pattern size, begin to check the current character against the first character of the pattern, if they match then begin a second loop checking the remainder of the pattern against the input string. If this loop goes all the way through and all characters match then copy everything from the beginning of the input string to the current character - 1 into your aforementioned buffer, and when I say copy from the beginning I mean you have some variable denoting where you last copied from, and by default this will be the start of the string. Once copied, increment this variable by the pattern size as well as the main loop's index value. Continue the process until the main loop terminates then zero terminate the buffer and return it.

You may not know the size required by the buffer so you can either continually re-allocate and copy the buffer whenever you find a pattern match, or create a buffer that's more than large enough for this operation and at the end you know its size so you allocate a new buffer of the exactly required size and return that, you could also use a stringstream if you don't want to manually allocate anything. Or use functions within the Boost library to do this, but manually coding it is much cooler .

IanM
Retired Moderator
22
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 4th Feb 2009 14:13 Edited at: 4th Feb 2009 18:34
In no particular order (because you can move steps around and even combine them):
- Get the source string length
- Get the search string length
- Get the replacement string length
- Allocate a buffer of (source_size-search_size+replacement_size+1)
- Locate the search string in the source string
- Copy from the source string to the buffer up to but not including the search string
- Append the replacement string to the buffer
- Append from the end of the search string in the source string to the buffer
- Free the source string

I had great fun ( ) doing this and optimising it for my DBPro string plug-in.

... or you can do the equivalent with std::string or std::stringstream, which will be slower, but may be a little easier.

[edit]replaced 'slow' with 'slower' which is what I intended to say.

dark coder
22
Years of Service
User Offline
Joined: 6th Oct 2002
Location: Japan
Posted: 4th Feb 2009 16:01
Interesting. (interesting)... (interesting...echo)

AlexI
19
Years of Service
User Offline
Joined: 31st Dec 2004
Location: UK
Posted: 4th Feb 2009 23:36
IanM if you have already written the function for dbpro can I see the source please?

Thanks,
Alex

IanM
Retired Moderator
22
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 5th Feb 2009 00:22
That code is optimised until it's not straight forward any more, so I'll give you the simplified version that follows what I posted earlier:


That can be used like so:


Remember to free the returned string at some point.
Also, this code was written using the GCC compiler, so you may need to remove the 'std::' part from some of the functions or replace that with a leading underscore or two to get it to compile under VC++. If you have problems with that, I'll clean it up tomorrow.

AlexI
19
Years of Service
User Offline
Joined: 31st Dec 2004
Location: UK
Posted: 5th Feb 2009 12:45 Edited at: 5th Feb 2009 12:48
Thank you very much for this code

I do get a type error though:


Error Line:


All Code:



Any idea?

Thanks again

IanM
Retired Moderator
22
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 5th Feb 2009 14:22 Edited at: 5th Feb 2009 14:22
Change this line:
char* Found = std::strstr( Source, Search );

To this:
const char* Found = std::strstr( Source, Search );

I'm not sure whether that's a mistake in G++ that allowed me to do that or not - it shouldn't have. If Source is const char*, the return type should be const char* too.

AlexI
19
Years of Service
User Offline
Joined: 31st Dec 2004
Location: UK
Posted: 5th Feb 2009 16:19 Edited at: 5th Feb 2009 16:20
Thanks, the code compiles now But it always returns true instead of the search & replace text.

Here is the new code:



IanM
Retired Moderator
22
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 5th Feb 2009 18:21
No, it works just fine - the problem is being caused by you using .NET to print the string. I'd guess that it's simply testing to see if the pointer is set or not, and displaying the boolean result.

BTW, you're also leaking memory by continually looping like that - IIRC, raw C++ pointers are not garbage collected (although I could be wrong).



AlexI
19
Years of Service
User Offline
Joined: 31st Dec 2004
Location: UK
Posted: 5th Feb 2009 20:10
Thanks it works great

I didn't have DarkGDK at work so I just tried using the console template on vc++

AlexI
19
Years of Service
User Offline
Joined: 31st Dec 2004
Location: UK
Posted: 5th Feb 2009 20:51 Edited at: 5th Feb 2009 21:18
One small problem, at the moment it ends after the first occurrence of the string. How can I get it to replace all occurrences?

Thanks,
Alex

EDIT:

Worked it out:



IanM
Retired Moderator
22
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 5th Feb 2009 21:11 Edited at: 5th Feb 2009 21:12
That's one way, but it results in lots of memory allocations, and you have a memory leak.



Another way is to count the number of search strings in the source, allocate enough memory to hold the final string (SourceLen - (Count * SearchLen) + (Count * ReplaceLen) + 1), then copy the source & replace strings to the buffer piece by piece. It's a little more involved, but you have the tools there already as it's only an extension of what I've already shown you.

AlexI
19
Years of Service
User Offline
Joined: 31st Dec 2004
Location: UK

Login to post a reply

Server time is: 2024-11-25 13:27:53
Your offset time is: 2024-11-25 13:27:53