Working with strings and replaciment.

BlitzMax Forums/BlitzMax Beginners Area/Working with strings and replaciment.

Ryan Burnside(Posted 2008) [#1]
Is there a good way to replace a position value inside a string with another letter?

Strings can be treated as arrays so why can't I replace

String[x] with a new character value?

This code does not work, ss is the string.
ss[4] = "0"


Bremer(Posted 2008) [#2]
Marks answer in this thread

http://blitzmax.com/Community/posts.php?topic=61525#687672

Seem to say that strings are readonly, so you cannot directly replace characters within the string like that.

You would probably have to make something with slicing where you take the first part up until the character you want to replace, add to that the character you want and then add the slice of the rest of the string from the character after the one you are replacing. If that makes sense.

[edit]

Searching a bit, I found these two functions that Perturbatio posted in a thread many moons ago:

stringy:String ="something"
StrInsert(stringy, "test", 4)
Print Stringy
StrReplaceIndex(stringy, "-", 4)
Print stringy

'	Inserts inString into the SourceStr at the specified index and expands the string to accommodate the change
Function StrInsert(SourceStr:String Var, inString:String, Index:Int)
	SourceStr = SourceStr[..Index] + inString + SourceStr[Index..]
End Function
'	Replaces replaceString with character at index
Function StrReplaceIndex(SourceStr:String Var, replaceString:String, Index:Int)
	SourceStr = SourceStr[..Index] + replaceString + SourceStr[Index+1..]
End Function



grable(Posted 2008) [#3]
Splicing/String creation isnt a particularly fast operation.
So if your gonna do this in a loop (or just need more speed) you can use a Byte[]/Byte Ptr and convert it to a String when your done.


Jesse(Posted 2008) [#4]
this works:
ss[4]= asc("0")


Gabriel(Posted 2008) [#5]
this works:

No it doesn't. It doesn't even compile.


Jesse(Posted 2008) [#6]
I am sorry. I did not even tryed it I just thought it would.
I remember using it in a program I did but I could be wrong.

what I don't understand is why it doesn't compile.
I even tryed this:
Local  ss:String = "   a "
Local a$ = "0"
ss[4] = a[0]
Print ss[4]

it gives me the error "expresion must be a variable".
I think it's a bug.

anybody has a good explanation why either of my examples cause a error? Maybe I don't understand it.


plash(Posted 2008) [#7]
Its very simple, its just not a feature yet - even though its standard to access strings as arrays in some languages.


Jesse(Posted 2008) [#8]
I guess so. But why have "varptr" access string address when it is only good for everything else but strings?


Brucey(Posted 2008) [#9]
Seem to say that strings are readonly

Yep, strings are meant to be immutable.

Although it's possible to change the contents of them (so long as you aren't changing the size).


Brucey(Posted 2008) [#10]
And just for fun....

stringmerge.bmx
SuperStrict

Import BRL.Blitz

Import "stringmerge.cpp"

Function MergeStrings(src:String, merge:String, start:Int)
	bmx_mergestrings(src, merge, start)
End Function

Extern
	Function bmx_mergestrings(src:String, merge:String, start:Int)
End Extern


Local src:String = "One Two Three Four"
Local mrg:String = "ABCEDF"

Print "-------"
Print src
Print mrg

MergeStrings(src, mrg, 4)

Print "-------"
Print src


stringmerge.cpp
#include "blitz.h"

extern "C" {

	void bmx_mergestrings(BBString * src, BBString * merge, int start);

}


void bmx_mergestrings(BBString * src, BBString * merge, int start) {

	BBChar *p,*q;
	int srcLength = src->length;
	int mergeLength = merge->length;
	int count;
	
	if (srcLength <= start || mergeLength == 0) {
		return;
	}
	
	count = srcLength - start;
	if (count > mergeLength) {
		count = mergeLength;
	}
	p = src->buf + start;
	q = merge->buf;

	for (int i = 0; i < count; i++) {
		*p++ = *q++;
	}

}


Merges "merge" into "src" at the given "start" index in "src".

Should be faster than a string slice/concat operation, but use at your own risk :-p


Jesse(Posted 2008) [#11]
Brucey, what do I need to do to compile the sample with the c source code. I keep getting a bunch of error when I try to execute your sample bmx file. I want to try a few variations of that c source code once I figure out how to compile them. I know I can figure out how to replace single bytes/chars from a source string using that simple concept/example thanks in advance.

I have MingW installed. I have Rebuild all modules so I know it is installed correctly.


Dreamora(Posted 2008) [#12]
the c file makes very little sense. it imports blitz.h locally but the bmx file above imports it locally as well?

only makes sense if the whole stuff would be within brl.blitz.mod and that hopefully isn't the place it is meant to be.


Brucey(Posted 2008) [#13]
the c file makes very little sense. it imports blitz.h locally but the bmx file above imports it locally as well?

Indeed.

Jesse, what errors are you getting exactly?


Jesse(Posted 2008) [#14]
I tested it by putting both files under blitz.mod "also" just to try to get it to work but I keep getting these errors:
Building teststring
Compiling:stringmerge.cpp
C:/Documents and Settings/Jesse/Desktop/strings/stringmerge.cpp:2:2: invalid preprocessing directive #Include
C:/Documents and Settings/Jesse/Desktop/strings/stringmerge.cpp:4: error: expected constructor, destructor, or type conversion before string constant
C:/Documents and Settings/Jesse/Desktop/strings/stringmerge.cpp:4: error: expected `,' or `;' before string constant
C:/Documents and Settings/Jesse/Desktop/strings/stringmerge.cpp:11: error: variable or field `bmx_mergestrings' declared void
C:/Documents and Settings/Jesse/Desktop/strings/stringmerge.cpp:11: error: `BBString' was not declared in this scope
C:/Documents and Settings/Jesse/Desktop/strings/stringmerge.cpp:11: error: `src' was not declared in this scope
C:/Documents and Settings/Jesse/Desktop/strings/stringmerge.cpp:11: error: `BBString' was not declared in this scope
C:/Documents and Settings/Jesse/Desktop/strings/stringmerge.cpp:11: error: `merge' was not declared in this scope
C:/Documents and Settings/Jesse/Desktop/strings/stringmerge.cpp:11: error: `Int' was not declared in this scope
C:/Documents and Settings/Jesse/Desktop/strings/stringmerge.cpp:11: error: initializer expression list treated as compound expression
C:/Documents and Settings/Jesse/Desktop/strings/stringmerge.cpp:11: error: expected `,' or `;' before '{' token
Build Error: failed to compile C:/Documents and Settings/Jesse/Desktop/strings/stringmerge.cpp
Process complete


Just to make it clear, I installed MingW with the istallation provided by the istaller link suppled by, I thik it was, Yan. where MingW is installed under program files. Might that be the problem?


Dreamora(Posted 2008) [#15]
the place where mingw is installed is unimportant. there are only 3 important things:

1. c:\....\Mingw\bin must be within path environmental variable
2. There must be an environmental variable MingW which points to the mingw path
3. You must have MingW 5.1.X and higher installed and point to this one.


Jesse(Posted 2008) [#16]
1 yes, it is there.
2 yes, it is.
3 yes, I have it.


grable(Posted 2008) [#17]
@Jesse: You saved the file via maxide didnt you? the end of the first line of the error message is a dead giveaway ;)

Try using something else when pasting non-bmx files from the forum.


Jesse(Posted 2008) [#18]
That is funny. Thanks grable. I forgot all about the upper case and lowercase rule in c. I did use Maxide to to save it. That took care of the problem. Years sence I used C. guess I got to remove the spiderwebs out of that part of the brain.
Thanks grable, Dreamora, and Brucey for your help. Always apreciated.

and they don't have to be in the mod's folder