How to EDIT the value of an existing string

Windows specific questions.
Post Reply
martago
Posts: 3
Joined: Apr 10, 2018 17:39

How to EDIT the value of an existing string

Post by martago »

I am unable to find an easy and direct way to edit a string with a pre-existing value/content. INPUT or LINE INPUT overrides the existing value with whatever you type. I want to edit the pre-existing value, changing its content at will.

Anyway can suggest a solution? Thanks.
Vortex
Posts: 118
Joined: Sep 19, 2005 9:50

Re: How to EDIT the value of an existing string

Post by Vortex »

Hello,

You could check the FreeBASIC manual, here are the string handling functions :
Working with Substrings

Left

Returns a substring of the leftmost characters in a string.

Mid (Function)

Returns a substring of a string.

Right

Returns a substring of the rightmost characters in a string.

LCase

Returns a copy of a string converted to lowercase alpha characters.

UCase

Returns a copy of a string converted to uppercase alpha characters.

LTrim

Removes surrounding substrings or characters on the left side of a string.

RTrim

Removes surrounding substrings or characters on the right side of a string.

Trim

Removes surrounding substrings or characters on the left and right side of a string.

InStr

Returns the first occurrence of a substring or character within a string.

InStrRev

Returns the last occurrence of a substring or character within a string.

Mid (Statement)

Copies a substring to a substring of a string.

LSet

Left-justifies a string.

RSet

Right-justifies a string.
You would like to learn about the Mid function.

Also :

viewtopic.php?t=27217
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How to EDIT the value of an existing string

Post by fxm »

If you wish a pure FreeBASIC solution, the following 'myLineInput()' subroutine simulates a simplified 'Line Input' feature but supporting a potential predefined string, by using a looping around the 'Inkey' keyword.
The only supported control keys are 'BkSp', 'Del', 'Right', 'Left', 'Esc' (and 'Enter'), and all this in "insert" mode:

Code: Select all

Sub myLineInput(ByRef prompt As String = "", Byref inputline As String = "", ByVal sleeptime As Integer = 15)
    Dim As String inputchr
    Dim As Integer cursor
    Dim As Integer cursor0
 
    cursor = Len(inputline)
    Locate  , , 0
    Print prompt & " ";
    cursor0 = Pos()
    Print inputline & "_";
    Do
        inputchr = Inkey
        If inputchr <> "" Then
            If inputchr >= Chr(32) And inputchr < Chr(255) Then
                inputline = Left(inputline, cursor) & inputchr & Mid(inputline, cursor + 1)
                cursor += 1
            ElseIf inputchr = Chr(08) And Cursor > 0 Then                         'BkSp
                cursor -= 1
                inputline = Left(inputline, cursor) & Mid(inputline, cursor + 2)
            ElseIf inputchr = Chr(255) & "S" And Cursor < Len(inputline) Then     'Del
                inputline = Left(inputline, cursor) & Mid(inputline, cursor + 2)
            ElseIf inputchr = Chr(255) + "M" And Cursor < Len(inputline) Then     'Right
                Cursor += 1
            ElseIf inputchr = Chr(255) + "K" And Cursor > 0 Then                  'Left
                Cursor -= 1
            End If
            If inputchr = Chr(27) Then                                            'Esc
                Locate  , cursor0
                Print Space(Len(inputline) + 1);
                inputline = ""
                cursor = 0
            End If
            Locate  , cursor0
            Print Left(inputline, cursor) & "_" & Mid(inputline, cursor + 1) & " ";
        End If
        Sleep sleeptime, 1
    Loop Until inputchr = Chr(13)
    Locate  , cursor0
    Print inputline & " "
End Sub

Dim As String s = "FreeBASIC"
myLineInput("Enter a compiler name?", s)  '' or: myLineInput "Enter a compiler name?", s
Print "You entered: '" & s & "'"

Sleep
[edit]
Improved 'myLineInput()' ending.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: How to EDIT the value of an existing string

Post by dodicat »

Another method:

Code: Select all


dim shared as long toggle

Function findAndReplace(instring As String,find As String,replace As String) As String
    dim as string s=instring
    dim as long position=Instr(s,find)
    While position>0
        s=Mid(s,1,position-1) & replace & Mid(s,position+Len(find))
        position=Instr(position+Len(replace),s,find)
    Wend
    return s
End Function

Sub readkey(x As Long,y As Long,st As String,message As String,clr As Ulong)
    Dim As String i=""
    Static As String j,blink
    Var c=Color
    i=Inkey
    If Left(i,1)=Chr(08) Then j=Mid(j,1,Len(j)-1)
    Select Case Left(i,1)
    Case Chr(0) To Chr(254)
        If Left(i,1)<>Chr(08) Then
            j=j+Left(i,1)
        End If
    End Select
    If Frac(Timer)>.5 Then blink=" " Else blink="_"
    If Left(i,1)=Chr(27) Then j=""
    If i<>Chr(13) Then
        Locate x,y,0
        Color clr
        Print  st & j & blink 
        Color c
    Else
        j=Rtrim(j,Chr(13))
        message=j
        j=""
        if toggle=0 then toggle=1:return
        if toggle=1 then toggle=0
    End If
End Sub

screen 12
dim  as string g,f,r,cr
g="abcdefghijklmnopqrstuvwxyz"
windowtitle "press F1 to end"
do
      screenlock
      cls
      locate 1,3
      print g
      if toggle=0 then readkey(3,3,"find  ",f,3)
      if toggle=1 then readkey(3,3,"replace with  ",r,3)
      if len(r) then g=FindAndReplace(g,f,r):cr=r:r=""
      locate 7,3
      print "find '";f;"'"
      locate 9,3
      print "replace with '";cr;"'"
      screenunlock
      sleep 10
      loop until multikey(&h3B)
 
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: How to EDIT the value of an existing string

Post by deltarho[1859] »

This is worth looking at for ideas if nothing else. String functions (32/64 bit ANSI only)
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: How to EDIT the value of an existing string

Post by grindstone »

Maybe this snippet fits your needs. I once wrote it to edit predefined strings. Through the years it grew and grew, so meanwhile, for the purpose you requested, it's got some overhead, but it can still simply edit an existing string. Just ignore the several modes and the callback option if you don't need them.

stringmod.bi:

Code: Select all

Type tJoyBack
	up_ As String
	right_ As String
	down_ As String
	left_ As String
End Type
Dim Shared tJoyBackZero As tJoyBack

Declare Operator = (jr1 As tJoyBack, jr2 As tJoyBack) As Integer
Operator = (r1 As tJoyBack, r2 As tJoyBack) As Integer
	If r1.up_ <> r2.up_ Then Return 0
	If r1.right_ <> r2.right_ Then Return 0
	If r1.down_ <> r2.down_ Then Return 0
	If r1.left_ <> r2.left_ Then Return 0
	Return -1
End Operator

Operator <> (r1 As tJoyBack, r2 As tJoyBack) As Integer
	If r1.up_ <> r2.up_ Then Return -1
	If r1.right_ <> r2.right_ Then Return -1
	If r1.down_ <> r2.down_ Then Return -1
	If r1.left_ <> r2.left_ Then Return -1
	Return 0
End Operator

Type tMouseBack
	left_ As String
	middle_ As String
	right_ As String
	forward_ As String
	back_ As string
End Type
Dim Shared tMouseBackZero As tMouseBack	

Operator = (r1 As tMouseBack, r2 As tMouseBack) As Integer
	If r1.left_ <> r2.left_ Then Return 0
	If r1.middle_ <> r2.middle_ Then Return 0
	If r1.right_ <> r2.right_ Then Return 0
	If r1.forward_ <> r2.forward_ Then Return 0
	If r1.back_ <> r2.back_ Then Return 0
	Return -1
End Operator

Operator <> (r1 As tMouseBack, r2 As tMouseBack) As Integer
	If r1.left_ <> r2.left_ Then Return -1
	If r1.middle_ <> r2.middle_ Then Return -1
	If r1.right_ <> r2.right_ Then Return -1
	If r1.forward_ <> r2.forward_ Then Return -1
	If r1.back_ <> r2.back_ Then Return -1
	Return 0
End Operator

Declare Function stringmod(text As String = "", mode As Integer = 0, _
                           mouseback As tMouseBack = tMouseBackZero, _
                           joyback As tJoyBack = tJoyBackZero, _
                           callback As Any Ptr = 0) As String
Declare Function joysubst OverLoad () As Integer
Declare Function joysubst (top_ As String, right_ As String, _
                           left_ As String, bottom_ As String) As String
Declare Function joysubst (joyback As tJoyBack) As String
Declare Function mousesubst OverLoad (left_ As String = "", middle_ As String = "", _
                                     right_ As String = "", forward_ As String = "", _
                                     back_ As String = "" ) As String
Declare Function mousesubst(mouseback As tMouseBack) As String

Function stringmod(text As String = "", mode As Integer = 0, _
                           mouseback As tMouseBack = tMouseBackZero, _
                           joyback As tJoyBack = tJoyBackZero, _
                           callback As Any Ptr = 0) As String
'the submission of 'mode' is optional, default is 0
'mode0 --> normal function
'mode1 --> returns after 'arrow up', 'arrow down', 'screen up' or 'screen down'
'mode2 --> treats joystick movements like arrow keys (up, down, right, left)
'mode4 --> only sets the variable 'lasttext' and returns
'mode8 --> adds a Chr(27) at the beginning of the retrun string if 'esc' key is pressed 

'if  'mouseback' is submitted as a 6-character string (each 2 characters for left/mid/right),
' mouseklicks are treated like keystrokes.

'if a pointer to a callback routine is submitted, the input loop is redirected to this 
' routine, which can optional return a string that is treated like a keyboard input afterwards.
    
  Dim As Integer ze, sp, co, gi, lock_, ms, mz, wheel, buttons, length
  Dim As Single joyx, joyy
  Dim As String g, remember, txt
  Dim plugin As Sub (address As Any Ptr, length As Any Ptr)
    
  Static As String lasttext, g_back
  Static As Integer mousewheel
     
  If (mode And 4) Then
  	lasttext = text + " "
  	Return text
  EndIf
  
  If lasttext = "" Then
  	lasttext = " "
  EndIf
  
  txt = text + " "
  remember = txt
  co = Pos 'cursor offset
  ze = CsrLin
  sp = Len(txt) 'pointer to the character under the cursor
  lock_ = 0
      
  Locate ze, co, 1
  Print txt;
  Locate ze, sp+co-1, 1
  
  
  Do
    'input
    plugin = callback 'set pointer to the plugin
    If (callback <> 0) And (g_back = "") Then 'call plugin
    	g_back = String(200,Chr(0)) 'allocate memory for the return string
    	length = Len(g_back) 'max length of the return string
    	plugin(StrPtr(g_back),@length) 'call plugin
      g_back = Left(g_back,length) 'write return string to buffer
    EndIf
    
    If (mouseback <> tMouseBackZero) Then
  		g_back += mousesubst(mouseback)
    EndIf
		     
  	If (joyback <> tJoyBackZero) Then 'treats joystick like keys
	    g_back += joysubst(joyback)
  	EndIf
           
    If g_back = "" Then
    	g = InKey
    Else 'process return string
    	If Left(g_back,1) = Chr(255) Then 'control character
    		g = Left(g_back,2) 'imitated keystroke
    		g_back = Mid(g_back,3) 'shorten return string
    	Else 'normal character
    		g = Left(g_back,1) 'imitated keystroke
    		g_back = Mid(g_back,2) 'shorten return string
    	EndIf
    EndIf
        
    If Len(g) = 1 Then 'normal character
    	If g[0] > 31 Then 'character
        txt = Left(txt, sp - 1) + g + Mid(txt, sp)
        sp += 1
        Locate ze, co, 0
        Print txt;
        Locate ze, sp+co-1, 1
    	Else 'control character
        Select Case g[0] 
        	Case 8 ' back key
            If sp > 1 Then
              txt = Left(txt, sp - 2) + Mid(txt, sp)
              sp -= 1
              Locate ze, co, 0
              Print txt;
              Locate ze, sp+co-1, 1
            End If
        	Case 27 'esc
            If (mode And 8) Then
            	txt = Chr$(27) + txt
            Else
            	txt = remember 'old string
            EndIf
            g = Chr$(13) 'terminate
        End Select
      End If
    ElseIf Len(g) = 2 Then 'control character
    	gi = g[1] 
      Select Case gi 'control character
      	Case 75 'left arrow -> cursor left
          If sp > 1 Then
            sp -= 1
            Locate ze, sp+co-1, 1
          End If
      	Case 77 'right arrow -> cursor right
          If sp < Len(txt) Then
            sp += 1
            Locate ze, sp+co-1, 1
          ElseIf txt = " " Then 'set old string
          	txt = lasttext
          	sp = Len(txt)
          	Print txt;
          	Locate ze, sp+co-1, 1
          End If
      	Case 14 'back -> delete character left of cursor
          If sp > 1 Then
            txt = Left(txt, sp - 1) + Mid$(txt, sp)
            sp -= 1
            Locate ze, co, 0
            Print txt;
            Locate ze, sp+co-1, 1
          End If
      	Case 83 'del -> delete character right of cursor
          If sp < Len(txt) Then
            txt = Left(txt, sp - 1) + Mid$(txt, sp + 1)
            Locate ze, co, 0
            Print txt;
            Locate ze, sp+co-1, 1
          End If
      	Case 71 'pos1 -> set cursor to the beginning of the string
          sp = 1
          Locate ze, sp+co-1, 1
      	Case 79 'end -> set cursor to the end of the string
          sp = Len(txt)
          Locate ze, sp+co-1, 1
      	Case Else
      		If (mode And 1) Then
            txt = g + Chr$(ze) + Chr$(co) + txt 'return control character and cursor position
            g = Chr$(13)
          EndIf
      End Select
    Else 'no key
    	Sleep 1
    End If
  Loop Until g = Chr$(13) 'return
		
  lasttext = txt
  Return Left(txt, Len(txt) - 1)
  Locate ze, sp+co-1, 0 'cursor off
             
End Function

Function joysubst () As Integer
	
	Dim As Single joyx, joyy
	Dim As Integer buttons, output_
	Static As Integer lock_ = 0
	Static As Double locktime
	
	output_ = 0 'default value no key pressed
		
	If GetJoystick (0, buttons, joyx, joyy) Then
		'no joystick connected
	Else
		If joyx < -.5 Then 'left
		  output_ = 4
		ElseIf joyx > .5 Then 'right
			output_ = 2
		EndIf
		If joyy < -.5 Then 'top
			output_ = 1
		ElseIf joyy > .5 Then 'bottom
			output_ = 3
		EndIf
	EndIf
	
	If output_ = 0 Then 'no key pressed, set delay to 0
		lock_ = 0
	EndIf

	Select Case lock_ 'delay mode
		Case 0 'immediate execution 
			If output_ Then 'key pressed
				lock_ = 1 'delay mode
			  locktime = Timer + 0.3 'delay for 1st keystroke
			EndIf
		Case 1 'key is held down
			If Timer > locktime Then 'check if delay time is over
				lock_ = 2 'repeat mode
				locktime = Timer + 0.07 'delay value for repetition mode
			Else 'delay time not over
				output_ = 0
			EndIf
		Case 2 'delay mode
			If Timer > locktime Then 'check if delay time is over
				locktime = Timer + 0.07 'set time for the next delay loop
			Else 'delay time not over
				output_ = 0
			EndIf
	End Select
	
	Return output_
  
End Function

Function joysubst (up_ As String, right_ As String, _
                   down_ As String, left_ As String) As String
			
	Select Case joysubst()
		Case 0 'no key
			Return ""
		Case 1 'up
			Return up_
		Case 2 'right
			Return right_
		Case 3 'down
			Return down_
		Case 4 'left
			Return left_
	End Select
	
End Function

Function joysubst (joyback As tJoyBack) As String
			
	Select Case joysubst()
		Case 0 'no key
			Return ""
		Case 1 'top
			Return joyback.up_
		Case 2 'right
			Return joyback.right_
		Case 3 'bottom
			Return joyback.down_
		Case 4 'left
			Return joyback.left_
	End Select
	
End Function

Function mousesubst(mouseback As tMouseBack) As String
	Return mousesubst(mouseback.left_, mouseback.middle_, mouseback.right_, _
	                 mouseback.forward_, mouseback.back_)
End Function

Function mousesubst (left_ As String = "", middle_ As String = "", _
                    right_ As String = "", forward_ As String = "", _
                    back_ As String = "") As String
	Dim As Integer ms, mz, wheel, buttons
	Static As Integer mousewheel
	
	GetMouse (ms,mz,wheel,buttons)
	If (buttons And 1) Then 'left mouse button
		Function = left_
	ElseIf (buttons And 4) Then 'mid mouse button
		Function = middle_
	ElseIf (buttons And 2) Then 'right mouse button
		Function = right_
	EndIf
		    	
	If wheel < mousewheel Then
		Function = back_ 'mouse wheel back
		mousewheel = wheel
	ElseIf wheel > mousewheel Then
		Function = forward_ 'mouse wheel forward
		mousewheel = wheel
	EndIf
	
	Do 'wait for mouse button release
		GetMouse (ms,mz,wheel,buttons)
		Sleep 1
	Loop While buttons

End Function
example.bas

Code: Select all

#Include "stringmod.bi"

Dim As String g = "Edit me"
g = stringmod(g)
Print 
Print g

Print "OK"

Sleep
martago
Posts: 3
Joined: Apr 10, 2018 17:39

Re: How to EDIT the value of an existing string

Post by martago »

Thank you for your suggestions. I think it should exist a direct FB instruction for this common request.

Bye for now.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: How to EDIT the value of an existing string

Post by jj2007 »

Code: Select all

  Let esi=Input$("What's your hobby? ", "FreeBasic")
  MsgBox 0, esi, "Your hobby:", MB_OK
If their is sufficient interest, I can dig out the Windows code for Input$()
Post Reply