Justification of data in strings

Just starting out? Need help? Post your questions and find answers here.
miskox
User
User
Posts: 95
Joined: Sun Aug 27, 2017 7:37 pm
Location: Slovenia

Justification of data in strings

Post by miskox »

Are there any built-in functions for string justification?

If we want to create fixed length fields using lots of spaces just doesn't look nice:

Code: Select all

Sequence_number Customer_number ____________ITEM____________ Value
--------------- --------------- ---------------------------- -----
              1           20000 itemname1                      100
              2           30001 itemname2                      200

Code: Select all

string1$="AA"
string2$="B"
numeric1.i=10
numeric2.i=200
Ljustified$=Left(string1$+"          ",5)
Debug "_"+Ljustified$+"_"
Rjustified$=Right("        "+string2$, 5)
Debug "_"+Rjustified$+"_"
Ljustified$=Left(Str(numeric1)+"            ",5)
Debug "_"+Ljustified$+"_"
Rjustified$=Right("        "+Str(numeric2), 5)
Debug "_"+Rjustified$+"_"
Output:

Code: Select all

_AA   _
_    B_
_10   _
_  200_
What we need is something like f$fao() in DCL on OpenVMS (see https://vmssoftware.com/docs/VSI_DCL_DICT_VOL_I.pdf).

Code: Select all

f$fao("!5SL", number)
;total number of characters is 5 with 'number' added (same as Right("        "+Str(numeric), 5) )
; SL=leading space, ZL=leading zero

f$fao("!20AS"," ")
; inserts 20x spaces so we don't have to type them. Could be used in: Left(string$+f$fao("!100AS"," "),100) to justify left
Or am I missing something? I checked manual but can't find any function that would do this?

Thanks.
Saso
User avatar
STARGÅTE
Addict
Addict
Posts: 2067
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Justification of data in strings

Post by STARGÅTE »

I think you are looking for RSet() and LSet()
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
User avatar
Kiffi
Addict
Addict
Posts: 1353
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Re: Justification of data in strings

Post by Kiffi »

Take a look at LSet() And RSet()
Hygge
miskox
User
User
Posts: 95
Joined: Sun Aug 27, 2017 7:37 pm
Location: Slovenia

Re: Justification of data in strings

Post by miskox »

Yes! This is it! I don't know how I missed that (too many functions I guess).

Thank you both.
Saso
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Justification of data in strings

Post by netmaestro »

LSet and RSet are a good start but they're not very useful if you don't use a monospace font. With those commands and a monospace font you're cooking with gas.
BERESHEIT
miskox
User
User
Posts: 95
Joined: Sun Aug 27, 2017 7:37 pm
Location: Slovenia

Re: Justification of data in strings

Post by miskox »

netmaestro wrote: Thu Oct 06, 2022 3:36 pm LSet and RSet are a good start but they're not very useful if you don't use a monospace font. With those commands and a monospace font you're cooking with gas.
I need this for console app (data processing) so Console font is used.
Thanks for the tip.

Saso
AZJIO
Addict
Addict
Posts: 1318
Joined: Sun May 14, 2017 1:48 am

Re: Justification of data in strings

Post by AZJIO »

Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Justification of data in strings

Post by Olli »

Less useful, to center :

Code: Select all

Procedure.s CSet(a$, n, i = 1)
 Protected lenA = Len(a$)
 Protected overLen = n - lenA
 Protected leftSet = overLen / 2 + i * ((lenA ! n) & 1)
 Protected rightSet = n - leftSet - lenA
 ProcedureReturn Space(leftSet) + a$ + Space(rightSet)
EndProcedure
miskox
User
User
Posts: 95
Joined: Sun Aug 27, 2017 7:37 pm
Location: Slovenia

Re: Justification of data in strings

Post by miskox »

Olli wrote: Fri Oct 07, 2022 2:54 am Less useful, to center :

Code: Select all

Procedure.s CSet(a$, n, i = 1)
 Protected lenA = Len(a$)
 Protected overLen = n - lenA
 Protected leftSet = overLen / 2 + i * ((lenA ! n) & 1)
 Protected rightSet = n - leftSet - lenA
 ProcedureReturn Space(leftSet) + a$ + Space(rightSet)
EndProcedure
Thanks Olli! Great. I (or somebody else) might need it some day.

Saso
User avatar
STARGÅTE
Addict
Addict
Posts: 2067
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Justification of data in strings

Post by STARGÅTE »

Please keep in mind, RSet and LSet also truncate the strings, if they are longer than the given length.
Here is a CSet which considers this behavior and also has the optional filling character.

Code: Select all

Procedure.s CSet(String.s, Length.i, Character.s=" ")
	Protected Spaces.i = Length - Len(String)
	If Spaces > 0 ; Extend
		ProcedureReturn RSet(LSet(String, Length-Spaces>>1, Character), Length, Character)
	ElseIf Spaces < 0 ; Truncate
		ProcedureReturn Left(Mid(String, 1+(-Spaces)>>1), Length)
	Else
		ProcedureReturn String
	EndIf
EndProcedure

Debug CSet("Hello World!", 20)
Debug CSet("Hello World!", 20, "-")
Debug CSet("Hello World!", 8)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Justification of data in strings

Post by Olli »

STARGÅTE wrote: Sat Oct 08, 2022 10:17 am Please keep in mind, RSet and LSet also truncate the strings, if they are longer than the given length.
In this case, it would be wise to warn the truncation with a default symbol (arrows, ellipsis, ... )

Price of this house :

Code: Select all

 200,00
euros. :mrgreen:
Jeff8888
User
User
Posts: 38
Joined: Fri Jan 31, 2020 6:48 pm

Re: Justification of data in strings

Post by Jeff8888 »

If you would prefer to use proportional fonts, which look better, then you need to use different space size. Unicode offers different space sizes starting with characters 2000 (hex). Note size of normal space is 7, whereas for digits it is 13. So for example with Ariel fonts the appropriate space character is hex 2007.

To display right justified numbers in a table use a the command for each column Rset(Str(variable),length,char($2007))

Here is a simple program to show the widths of various characters for the font (change for your preference) in the program. Note digits and character $2007 have the same width. Also note minus sign has a smaller width, same as character $2004.

Code: Select all

If OpenWindow(0, 0, 0, 1000,500,"", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  font1= LoadFont(#PB_Any, "Arial MS Unicode",18)
  StartDrawing(WindowOutput(0) )
  DrawingFont(FontID(font1))
  For i=32 To 127
    Debug Str(i)+"  " +Chr(i)+ "  " +StrF(TextWidth(Chr(i)))
  Next
  For i=$2000 To $200B
    Debug Hex(i)+"  " +Chr(i)+ "  " +StrF(TextWidth(Chr(i)))
  Next
  StopDrawing()  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
End
Using this information here is a code snippet from a program I wrote to display a matrix

Code: Select all

 For i=1 To ncmps          ;For each row of B-Matrix  (note B is a square matrix)
          p$=RSet(Str(i),6,Chr($2007))
          For k=1 To ncmps        ;For each col of B-Matrix
            If Bmatrix(i,k)<0                                ;use slightly different spacing due to minus sign
              p$=p$+#CRLF$+RSet(StrF(Bmatrix(i,k)*10000.0,3),6,Chr($2007))
            Else
              p$=p$+#CRLF$+Chr($2004)+RSet(StrF(Bmatrix(i,k)*10000.0,3),5,Chr($2007))
            EndIf
          Next
          AddGadgetItem(#Table1,-1,p$) 
          If Mod(i,5)=0
            SetGadgetItemColor(#Table1,i-1,#PB_Gadget_BackColor,ColorBack3,#PB_All)
          EndIf
        Next
Post Reply