• Welcome to PlanetSquires Forums.
 

CWSTR and pointer arithmetic (zero vs one based)

Started by Paul Squires, July 04, 2018, 12:08:13 PM

Previous topic - Next topic

Paul Squires

CWSTR seems to handle pointer arithmetic based on one based rather than zero based?


#Define UNICODE
#Define _WIN32_WINNT &h0602 

#Include Once "windows.bi"
#Include Once "Afx\AfxStr.inc"

Using Afx

dim as CWSTR wszText = "This is my text."

' Use pointer indexing to get each character (zero based - incorrect)
for i as long = 0 to len(wszText) - 1
   ? wszText[i], wchr(wszText[i])
NEXT

?
?
' Use pointer indexing to get each character (one based - correct)
for i as long = 1 to len(wszText)
   ? wszText[i], wchr(wszText[i])
NEXT

' Shouldn't pointer indexing be ZERO based in order to stay consistent
' with the FB language?

? "Done"
Sleep

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

I think that it was thought as an alternative syntax for Char, that is one based, but you're right.

Changed to:


' ========================================================================================
' Returns the corresponding ASCII or Unicode integer representation of the character at
' the zero-based position specified by the nIndex parameter (0 for the first character,
' 1 for the second, etc.), e.g. value = cws[1]. ' Can't be used to change a value.
' ========================================================================================
PRIVATE OPERATOR CWStr.[] (BYVAL nIndex AS UINT) AS USHORT
   IF nIndex < 0 OR nIndex > (m_BufferLen \ 2) - 1 THEN EXIT OPERATOR
   ' Get the numeric character code at position nIndex
   OPERATOR = PEEK(USHORT, m_pBuffer + (nIndex * 2))
END OPERATOR
' ========================================================================================


Paul Squires

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

#3
To change a value using pointer arithmetic we need to use an intermediate pointer variable:


DIM AS CWSTR wszText = "This is my text."
DIM p AS WSTRING PTR = *wszText
p[1] = ASC("x")


or use casting:


(*wszText)[1] = ASC("x")
--or--
CAST(WSTRING PTR, *wszText)[1] = ASC("x")


When using the [] operator this way, there is not range checking. Therefore, make sure that the string is not empty and that the index does not exceed the range "[0, Len(wszText) - 1]". Outside this range, results are undefined.