Page 1 of 1

Double terminated string problem

Posted: Fri May 07, 2021 12:19 am
by lazi
Let's take the situation that we have a string which has a zero byte in there and not at the last position.

You may think that this is what happens when somebody lurking with dark occult code lines.
Just pour it with holy water and avoid it next time.

But please try to not questioning the origin of the problem. Even alchimie, the bad science was a great source of experiences. :)

So strings can have ordinary binary data. This is good. But what if we have a twisted string like this:

Code: Select all

t={72,111,108,108,121,0,119,111,111,100,0}
s$=ArrayToStr(t)
DebugPrint(s$)        
The last zero should terminate the string. But, yay! It has another zero byte!

DebugPrint() and a bunch of another functions stop at the first zero.
However for example if it is concatenated into an xml file it ruins the whole thing. This is what happened for me.

So, how can I drop the part from the first zero?
Findstring() can't be used with Chr(0) for search string. - Wrong usage/parameters for this command!
Iterating all over the strings to be safe would be slow and ugly.

Is there a way to get just the string (to the first zero) from a binary 'string'?

Re: Double terminated string problem

Posted: Fri May 07, 2021 1:19 am
by lazi
A possible solution:

Code: Select all

Function strnorm(s$)
	;it can happen that a string has a zero byte inside, not just the end of the string
	;this function crops the garbaged end from the string
	Local sl=FindStr(s$,"\000")
	Return (IIf(sl=False, s$, LeftStr(s$,sl)))
EndFunction         
Do you know a better one?

Re: Double terminated string problem

Posted: Fri May 07, 2021 8:30 am
by jPV
Hmm.. I think ArrayToStr() already cuts it, because if I do this:

Code: Select all

t={72,111,108,108,121,0,119,111,111,100,0}
s$=ArrayToStr(t)
DebugPrint(ByteLen(s$)) 
It prints 5.

About your function I see few issues there:
1) Why three zeroes in \000? Shouldn't \0 be enough?
2) FindStr() returns -1 if it doesn't find anything, so IIf(sl=-1...
3) If you want to optimize this, don't use IIf(), because it does the LeftStr() in all cases even when it's not necessary. This would be slightly faster solution: If sl=-1 Then Return(s$) Else Return(LeftStr(s$, sl))

Re: Double terminated string problem

Posted: Fri May 07, 2021 11:46 am
by lazi
Thanks jPV!
Yes I made a mistake with exchanging -1 and false.
Tested ArrayStr() speedwise and it is obviously slower than FindStr().

This is the fastest way I found yet:

Code: Select all

Function strnorm(s$)
	;it can happen that a string has a zero byte inside, not just the end of the string
	;this function crops the garbaged end from the string
	Local sl=FindStr(s$,"\0")
	If sl=-1 Then Return(s$)
	Return (LeftStr(s$,sl))
EndFunction