Fixed Length String handling

General FreeBASIC programming questions.
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Fixed Length String handling

Post by Munair »

dodicat wrote:As with many things in fb, a workaround is required, so, getting the best one is the immediate quest.

I think mid() is the easiest cast from fixed string to var string.
MID() is probably slower than LEFT() or RIGHT(). TRIM() should be avoided as it might erase intentional padded spaces.
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Fixed Length String handling

Post by Munair »

I stand corrected. MID() is slightly faster than LEFT() most of the time in my test:

Code: Select all

dim t as double
dim buffer1 as string * 10
dim buffer2 as string
dim n as integer

t=timer
for i as integer = 0 to 800000
	buffer1 = "some thing"
	n = rnd*10
	buffer2 = left(buffer1, n)
next
print timer - t

t=timer
for i as integer = 0 to 800000
	buffer1 = "some thing"
	n = rnd*10
	buffer2 = mid(buffer1, 1, n)
next
print timer - t

end
But the difference is really tiny.
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Fixed Length String handling

Post by Munair »

As stated in the other thread, a simple and perhaps logical solution to get a fixed length string copied including possible null characters:

Code: Select all

#define VLStr(s, n) Left(s, n)

dim buffer as string * 16
dim s as string

mid(buffer, 3) = "something else"
print "buffer: "; buffer
s = buffer
print "copy of buffer to s: "; s
' make Variable Length STRing copy
s = VLStr(buffer, 16)
print "copy of buffer to s by VLStr: "; s
sleep
end
Perhaps this could be refined or improved.
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Fixed Length String handling

Post by Munair »

dodicat wrote:I think mid() is the easiest cast from fixed string to var string.
It is also the most practical as it allows for omitting the extra parameter:

Code: Select all

#define VStr(s) Mid(s, 1)

type TT1
	s as string * 8
end type

type TT2
	v as longint
end type

function vs(v as longint) as string
	dim t1 as TT1
	dim t2 as TT2
	t2.v = v
	lset t1, t2
	return VStr(t1.s)
end function

function sv(s as string) as longint
	dim t1 as TT1
	dim t2 as TT2
	t1.s = s
	lset t2, t1
	return t2.v
end function

dim v as longint = 3044630875795881984
	print v
dim s as string = vs(v) 
	v = sv(s)
	print v

end
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Fixed Length String handling

Post by fxm »

Why not more simply:

Code: Select all

#define VStr(s) Mid(s, 1)

union TT
   s as string * 8
   v as longint
end union

function vs(v as longint) as string
   dim t as TT
   t.v = v
   return VStr(t.s)
end function

function sv(s as string) as longint
   dim t as TT
   t.s = s
   return t.v
end function

dim v as longint = 3044630875795881984
   print v
dim s as string = vs(v)
   v = sv(s)
   print v

sleep
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Fixed Length String handling

Post by Munair »

Thanks for sharing. I've been thinking about using a union too but haven't got around to actually implementing it. My current solution is based on older VB code.
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Fixed Length String handling

Post by Munair »

But more importantly, if LEN() and other string functions can figure out the actual length of a fixed length string, then why does the compiler stop at the first null character occurrence when the string is copied? Especially from fixed to fixed I consider it unexpected behaviour.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Fixed Length String handling

Post by fxm »

It also reminds me of an old discussion about using NULL or SPACE characters to fill the unused gaps of a fixed-length string:
viewtopic.php?f=3&t=17229
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Fixed Length String handling

Post by Munair »

fxm wrote:It also reminds me of an old discussion about using NULL or SPACE characters to fill the unused gaps of a fixed-length string:
viewtopic.php?f=3&t=17229
Recognizable discussion. I wouldn't go as far as to say that fixed length strings are buggy and that they should not be used. There is even an advantage with trailing null characters over spaces; when a fixed length string is assigned some text (starting at position 1), then that text is considered up until the null byte, leaving a clean copy upon reassignment. With spaces one has to trim the result in order to get rid of the unused string space. This can be a problem if the string should contain intentional trailing spaces. In QuickBASIC this was common practice:

Code: Select all

dim s as string * 10
dim r as string
s = "hello"
r = rtrim(s) + chr(32) + "world."
The only thing I would like to see changed is that currently the compiler ends the string (copy) as soon as it finds a null character, disregarding possible following non null characters before the end of the specified string length. Hence my remark that LEN() and other string functions such as LEFT() etc. do regard the entire string. Which begs the question, how do these functions know the fixed length, as the descriptor is not the same as for variable length strings.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Fixed Length String handling

Post by fxm »

Munair wrote:Which begs the question, how do these functions know the fixed length, as the descriptor is not the same as for variable length strings.
Only thanks to its declaration ('As String * N') that the compiler obviously knows.
Boris the Old
Posts: 139
Joined: Feb 04, 2011 20:34
Location: Ontario, Canada

Re: Fixed Length String handling

Post by Boris the Old »

There are two problems with FB's fixed string data type. Firstly, unlike other languages such as PowerBasic and COBOL, the FB fixed string is actually a ZString. And like a ZString, it doesn't allow embedded null characters. Secondly, the FB fixed string contains an extra null character to act as a field delimiter. This is a major problem when trying to map an FB Type to externally sourced data.

We create applications in both PowerBasic and COBOL, but use a common file system for both languages. Fixed length fields and embedded nulls are not only common - they are required. Extra embedded characters and truncated data transfer cannot be allowed.

Our solution is to use macros and fixed arrays to define the fixed fields, and custom routines to simulate the behaviour of data transfer. For example, truncating data to fit into a fixed field, or padding with blanks if the field is too long. It's a simple solution that gets around a very messy situation.

Rod
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Fixed Length String handling

Post by dodicat »

chr(0) doesn't truncicate a fixed length string.
(If a null character is chr(0))

Code: Select all


dim as string * 10 s
s="01234" + chr(0) + "56789"
print s

dim as string * 10 g=s
print g
sleep
 
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Fixed Length String handling

Post by fxm »

Especially when the assignment does not take into account the null character:

Code: Select all

dim as string * 10 s
s="01234" + chr(0) + "56789"

print s
for i as integer = 0 to len(s)
  print s[i]
next i

sleep
However, when it is really there, it is displayed as a space:

Code: Select all

dim as string * 10 s
s="01234" + chr(0) + "56789"

print s
for i as integer = 0 to len(s)
  print s[i]
next i

s[5] = 0
print s

sleep
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: Fixed Length String handling

Post by srvaldez »

Code: Select all

dim as string * 10 s
s="01234" + chr(0) + "56789"
print s

dim as string * 10 g=s
print g
s[5]=0
print s
g=s
print g
sleep
output

Code: Select all

0123456789
0123456789
01234 6789
01234
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: Fixed Length String handling

Post by srvaldez »

I think the forum database got messed up, one post shows up twice, if you delete the duplicate, it deletes both
Post Reply