Algorithm for counting the cursor in a line for the console

General FreeBASIC programming questions.
Post Reply
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Algorithm for counting the cursor in a line for the console

Post by VANYA »

Hi all!

How to make it easier to calculate the cursor position in the console if there are tabs in the text?
I must say right away that getting a position using standard means (csrlin, pos) is sooooo slow (it's just not applicable in this case). Therefore, I understand that only the manual version is needed. Assume that the tab character is always 4.
That is: there is, say, a text (more precisely, a buffer):

aa9a9aaa9a

Get the text on the screen:

Code: Select all

aa	a	aaa	a
How to find out quickly its last position? Or how to find out the position after the second nine? As you can see, 9 is a tab character.
Only the full calculation of the line from the beginning comes to mind (earch for all tab characters, calculating each until we reach the desired position). But it's kind of long if the string is long. When moving through the lines it will be quite "hard". And so the console draws slowly, and then there is such a load with a full line calculation every time for any operation.
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: Algorithm for counting the cursor in a line for the console

Post by VANYA »

So far I see only this option:

Code: Select all

function GetPositionInLine(pwsLine as Wstring ptr , iPosCurent as Long = -1) as LONG
	
	Dim As long iVirtualPos

	dim as Long iTabSize = 4
	
	if iPosCurent = -1 then
		
		iPosCurent = len(*pwsLine)-1
		
	EndIf

	for i As Long = 0 To iPosCurent
		
		If (*pwsLine)[i] = 9 Then
			
			Dim As Long iRest = iVirtualPos Mod iTabSize
			
			iVirtualPos += iTabSize - iRest
			
		Else
			
			iVirtualPos += 1
			
		EndIf
		
	Next
	
	return iVirtualPos
	
End Function
Maybe there is a better solution?
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Algorithm for counting the cursor in a line for the console

Post by dodicat »

Test, create six lines of the given string of Get the text on the screen.
Load these six lines into an array.
tally each line (for chr(9)) and load the positions into an array.

Code: Select all

Function tally (somestring As String,partstring As String,arr() As long) As long
    Dim As long i,j,ln,lnp,count,num
    Dim As boolean filler=false
    ln=Len(somestring)
    lnp=Len(partstring)
    start:
    count=0
    i=-1
    Do
        i+=1
        If somestring[i] <> partstring[0] Then Goto skip 
        If somestring[i] = partstring[0] Then
            For j=0 To lnp-1 
                If somestring[j+i]<>partstring[j] Then Goto skip
            Next j
        End If
        count+=1
        If filler = true Then arr(count)=i+1 
        i=i+lnp-1
        skip:
    Loop Until i>=ln-1 
    If filler = false Then Redim arr(1 to count) 'size is now known, repeat the operation to fil arr()
    num=count
    If filler=true Then Goto _return
    filler=true
    Goto start
    _return:
    Return num
End Function


Sub string_split(byval s As String,chars As String,result() As String)
    redim result(0)
    Dim As String var1,var2
Dim As long pst,LC=len(chars)
      #macro split(stri)
    pst=Instr(stri,chars)
    var1="":var2=""
    If pst<>0 Then
    var1=Mid(stri,1,pst-1)
    var2=Mid(stri,pst+LC)
    Else
    var1=stri
End if
    if len(var1) then 
    redim preserve result(1 to ubound(result)+1)
    result(ubound(result))=var1
    end if
    #endmacro
   Do
   split(s):s=var2
Loop Until var2=""
End Sub



dim as string s="aa	a	aaa	a"

dim as string g
for n as long=1 to 6
    g+=s+chr(10)
next
print "line","value"
redim as string lines()
'Get lines into array
string_split(g,chr(10),lines())



for n as long=lbound(lines) to ubound(lines)
    print n,lines(n)
next
print
print "aa9a9aaa9a   six lines  9 is a tab character."
'get positiond of chr(9) in each line
redim as long t()
print "(row column)"
for n as long=1 to ubound(lines)
   var c=tally(lines(n),chr(9),t()) 
   for m as long=1 to ubound(t)
       print "(";n;t(m);")";
   next m
   print
next n
sleep
 
I have a much faster string_split, this one is only to test.
The tally function is very fast.
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: Algorithm for counting the cursor in a line for the console

Post by VANYA »

Thank you for the example of dodicat!
Post Reply