Page 2 of 2

Re: how is a string terminated ?

Posted: Sat Jan 02, 2021 1:36 pm
by NicTheQuick
@mk-soft:
The indexed version is nice if you need random access to the characters or if you often have to jump around in the string. But I think it also has a slightly overhead if all you need is to iterate once through the string because every time the index has to be recalculated and added to the base pointer of the string.

Re: how is a string terminated ?

Posted: Sat Jan 02, 2021 2:04 pm
by mk-soft
You're right about that, NicTheQuick.

The handling of pointers must be practised, as one can also make mistakes very quickly here, which can lead to a crash of the programme.
PureBasic does not check the allowed access to the memory. That is the task of the programmer.

The changes from string to size must always be done with the string functions of PureBasic, as only this manages the memory for the string internally.
But this leads to the problem of working with pointers to the string, because you always get the pointer to the string and not the pointer to the variable where the pointer to the string is stored.

But here, too, there are possibilities to work with String ByREF (pointer to the string pointer).

I can also provide examples here if anyone is interested.

I don't want to demonise working with pointers here, because working with pointers is an elegant method of creating optimised programmes.

Re: how is a string terminated ?

Posted: Sat Jan 02, 2021 3:16 pm
by NicTheQuick
mk-soft wrote:I can also provide examples here if anyone is interested.
I only know about this way:

Code: Select all

EnableExplicit

Define text.String\s = "Hello World"

; The pointer of the string variable
Debug @text

; The pointer to the content of the string
Debug @text\s

; And another way to get the pointer to the content
Debug PeekI(@text)
but I don't think it works with native strings. Except they are fixed strings.

Re: how is a string terminated ?

Posted: Sat Jan 02, 2021 3:33 pm
by RASHAD
To neglect control characters

Code: Select all

Dim st.s(1)
st(0) = "Hellow "+Chr(8)+Chr(9)+"World"
For i = 0 To StringByteLength(st(0)) Step 2
  char = PeekA(@st(0)+i)
  If char > 31
    Debug Chr(PeekA(@st(0)+i))
  EndIf
Next

Re: how is a string terminated ?

Posted: Sat Jan 02, 2021 3:34 pm
by mk-soft
Unfortunately there is no native function in Purebasic to get the address of a native variable. However, you can create this yourself via ASM.
So you can also pass native variables ByREF to a function.

Unfortunately it is not as nice to implement as *Var = VarPtr(Var).

Code: Select all

;-TOP

Macro VarPtr(_Var_, _Pointer_)
  EnableASM
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    lea rax, _Var_
    mov _Pointer_, rax
  CompilerElse
    lea eax, _Var_
    mov _Pointer_, eax
  CompilerEndIf  
  DisableASM
EndMacro

; ****

Procedure.i MyFunction(*StringByRef.string)
  
  *StringByRef\s + " I Like PureBasic ;)"
      
EndProcedure

; ----

Define text.s, *pText.string

text = "Hello World!"
VarPtr(text, *pText)

Debug "Adress of variable = " + *pText
Debug "Contents of variable = " + *pText\s

Debug "Function with String ByREF"
MyFunction(*pText)
; MyFunction(VarPtr(Text)) ; Features Request
Debug "Result = " + text

; ----

Define text2.String\s = "Structured string Variable!"
Debug "Function with String ByREF (Structured string Variable)"
MyFunction(text2)
Debug "Result = " + text2\s

Re: how is a string terminated ?

Posted: Sat Jan 02, 2021 3:57 pm
by Saki
Don't make it so complicated, otherwise the questioner will have a crisis. :wink: :lol:

Re: how is a string terminated ?

Posted: Sat Jan 02, 2021 10:10 pm
by ludoke
I always want to make it as simple and as fast as possible.
I like the code from NicTheQuick,but I also want to thank the others for their thinking.

Code: Select all

EnableExplicit

Define text.s = "Hello World"
Define kar.s
Define *c.Character = @text

While *c\c
 ; Debug *c\c ; 87=W 
  kar.s= Chr(*c\c);instead of chr (*c\c) I can also use the ascii, which is again some code savings I think?
  Debug kar
If *c\c=87:Debug "87 found":endif  ;W found
If kar="W":Debug "W found":EndIf  
If kar="e":Debug "e found":EndIf
   *c + SizeOf(Character)
Wend

Re: how is a string terminated ?

Posted: Sat Jan 02, 2021 10:56 pm
by mk-soft
Its Unicode not ASCII since PB v5.5

You don't need the function Chr(...)

Code: Select all

If *c\c = 'W' :Debug "W (87) found":EndIf  ;W found

Re: how is a string terminated ?

Posted: Sun Jan 03, 2021 12:31 am
by Saki
The Pointer method is not faster than the Peek-Poke method.

I often compared this because I wanted the fastest method.
Many years ago this should have been the case with PB, but I don't really know.
Peek-Poke is like Goto just very Basic like.

It becomes very slow with Peek$, Poke$, ReadString, WriteString,
this should be avoided if possible when dealing with larger amounts of data, if you want high speed. :wink:

Re: how is a string terminated ?

Posted: Sun Jan 03, 2021 12:54 am
by infratec
Saki wrote:The Pointer method is not faster than the Peek-Poke method.

Code: Select all

; a.c = PeekC(*Buffer)
  PUSH   dword [p_Buffer]
  CALL  _PB_PeekC@4
  MOV    word [v_a],ax

Code: Select all

; a.c = *Buffer\c
  MOV    ebp,dword [p_Buffer]
  MOVZX  eax,word [ebp]
  MOV    word [v_a],ax
Without knowing the code of _PB_PeekC@4 :

I'm 100% sure the pointer method is faster.

Compiled with /commented PB 5.73 x86 in Windows 10 x64

Re: how is a string terminated ?

Posted: Sun Jan 03, 2021 1:17 am
by Mijikai
Pointers are faster.

Re: how is a string terminated ?

Posted: Sun Jan 03, 2021 1:48 am
by Saki
In practical use with very large amounts of data I often use peek and poke first until the code runs smoothly.
Then usually comes the optimization.
The disappointment was always quite big to see that it looks visually better with pointers, but no speed advantage was achieved.