Recent

Author Topic: [SOLVED]Formatting a numer right-justified with leading spaces  (Read 865 times)

tfurnivall

  • New Member
  • *
  • Posts: 43
I'm wrestling with the Format function (and losing).

I have a number which I want to right justify in a 2 character field (called Result).
Code: Pascal  [Select][+][-]
  1. [font=courier]
  2.          1          <indicates 10 characters
  3. 1234567890   <indicates single character positions
  4.  9  
  5. [/font]

If the number is in a variable CurrentSource, the code I believe that will be necessary is:
Code: Pascal  [Select][+][-]
  1. Result := Format ('%-2S',[CurrentSource]);
  2.  

However, when I run the code I get an exception:
Code: Pascal  [Select][+][-]
  1. Project SDLCOMP raised exception class 'EConvertError' with message
  2. Invalid argument index in format "%-2S"
  3.  

I have single quotes around the format string, even though Lazarus reports out the same string with double quotes!!
CurrentSource is an integer with a value of 1 (at the moment).

If I hover the cursor above a later part of the line, I get a note saying:
Code: Pascal  [Select][+][-]
  1. format('%-2S',[CurrentSource]) + '-';  =<Error: identifier not found "format" at start of expression>
  2.  

This seems to indicate that the format function is not being found, which is strange since I used it a few lines back!

All the documentation in the rtl seems to indicate that I can only use the '%-2S' construct if I am formatting a string. Which raises the question:

Does Lazarus have any means (at all) of formatting a numeric value right justified with leading spaces?

I'm going to stop now while I still have some head left to beat against the brick wall tomorrow. Any suggestions, comments, pointers appreciated!

Thanks

Tony
« Last Edit: May 26, 2025, 10:40:08 pm by tfurnivall »

dsiders

  • Hero Member
  • *****
  • Posts: 1436
Re: Formatting a numer right-justified with leading spaces
« Reply #1 on: May 25, 2025, 05:17:54 am »
I'm wrestling with the Format function (and losing).

I have a number which I want to right justify in a 2 character field (called Result).
Code: Pascal  [Select][+][-]
  1. [font=courier]
  2.          1          <indicates 10 characters
  3. 1234567890   <indicates single character positions
  4.  9  
  5. [/font]

If the number is in a variable CurrentSource, the code I believe that will be necessary is:
Code: Pascal  [Select][+][-]
  1. Result := Format ('%-2S',[CurrentSource]);
  2.  

However, when I run the code I get an exception:
Code: Pascal  [Select][+][-]
  1. Project SDLCOMP raised exception class 'EConvertError' with message
  2. Invalid argument index in format "%-2S"
  3.  

I have single quotes around the format string, even though Lazarus reports out the same string with double quotes!!
CurrentSource is an integer with a value of 1 (at the moment).

If I hover the cursor above a later part of the line, I get a note saying:
Code: Pascal  [Select][+][-]
  1. format('%-2S',[CurrentSource]) + '-';  =<Error: identifier not found "format" at start of expression>
  2.  

This seems to indicate that the format function is not being found, which is strange since I used it a few lines back!

All the documentation in the rtl seems to indicate that I can only use the '%-2S' construct if I am formatting a string. Which raises the question:

Does Lazarus have any means (at all) of formatting a numeric value right justified with leading spaces?

I'm going to stop now while I still have some head left to beat against the brick wall tomorrow. Any suggestions, comments, pointers appreciated!

Thanks

Tony

https://lazarus-ccr.sourceforge.io/docs/rtl/sysutils/format.html has examples (both code and output).
Preview the next Lazarus documentation release at: https://dsiders.gitlab.io/lazdocsnext

bytebites

  • Hero Member
  • *****
  • Posts: 717
Re: Formatting a numer right-justified with leading spaces
« Reply #2 on: May 25, 2025, 05:35:46 am »
Instead of wordy tantrum, complete code is better.

440bx

  • Hero Member
  • *****
  • Posts: 5466
Re: Formatting a numer right-justified with leading spaces
« Reply #3 on: May 25, 2025, 05:55:02 am »
All the documentation in the rtl seems to indicate that I can only use the '%-2S' construct if I am formatting a string. Which raises the question:

Does Lazarus have any means (at all) of formatting a numeric value right justified with leading spaces?
Yes, "S" is to format strings.  For a number (integer) you need to use "D".  IOW, try '%-2d'.  Lastly, as @dsiders suggested, it would be a good idea for you to review Format's documentation.

HTH.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

cdbc

  • Hero Member
  • *****
  • Posts: 2208
    • http://www.cdbc.dk
Re: Formatting a numer right-justified with leading spaces
« Reply #4 on: May 25, 2025, 08:25:46 am »
Hi
You can try this:
Code: Pascal  [Select][+][-]
  1. function GetTimestamp: string;
  2. const fmt = '[%.2d.%.2d.%.4d %.2d:%.2d:%.2d,%.3d] ';
  3. var
  4.   Y, M, D, hh, mm, ss, ms: Word;
  5. begin                                ///
  6.   try
  7.     DecodeDateTime(now,Y,M,D,hh,mm,ss,ms);
  8.     Result:= format(fmt,[D,M,Y,hh,mm,ss,ms]);
  9.   except
  10.     Result:= '['+DateTimeToStr(now)+']';
  11.   end;
  12. end;
I guess it's in the ballpark...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

jamie

  • Hero Member
  • *****
  • Posts: 6953
Re: Formatting a numer right-justified with leading spaces
« Reply #5 on: May 25, 2025, 02:59:14 pm »
I still use the old stuff for formatting.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   S:string;
  4. begin
  5.   WriteStr(S, DateTimeTostr(Now):20);
  6.   Caption := S;
  7. end;                                      
  8.  


The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 12866
Re: Formatting a numer right-justified with leading spaces
« Reply #6 on: May 26, 2025, 12:05:51 am »
Playing with the Format() instruction:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. uses
  3.   SysUtils;
  4. begin
  5.   WriteLn(Format('"%d"',   [123]));       // "   123"
  6.   WriteLn(Format('"%6d"',  [123]));       // "   123"
  7.   WriteLn(Format('"%-6d"', [123]));       // "123   "
  8.   WriteLn(Format('"%.6d"', [123]));       // "000123"
  9.   WriteLn;
  10.   WriteLn(Format('"%s"',   ['abc']));     // "abc"
  11.   WriteLn(Format('"%6s"',  ['abc']));     // "   abc"
  12.   WriteLn(Format('"%-6s"', ['abc']));     // "abc   "
  13.   WriteLn(Format('"%.6s"', ['abc']));     // "abc"
  14.  
  15.   ReadLn;
  16. end.

tfurnivall

  • New Member
  • *
  • Posts: 43
Re: Formatting a numer right-justified with leading spaces
« Reply #7 on: May 26, 2025, 09:30:10 pm »
Thanks to all who responded!

I accept the criticism about examples being better than rants - I'm trying to upload an example of what I'm trying to accomplish.

Thanks, also, to wp who posted some good examples. However they repeat the style of the documentation and use actual constants as the argument (value) to be formatted.

I'm hoping that it is actually possible to use a variable there, as otherwise I would need to code every possible numeric value to get the formatting to work. (reductio ad absurdissimum!)

I have attached (I write this before actually doing it) a file with what I'm trying to do. It's a simple form that has two fields: Input value and format code. There is also a checkbox to surround the format code with brackets (I'll try any little thing!), and button to actually try the formatting. There are also buttons to reset the form, and (most important button of all) to Exit.

It doesn't do what I expected!

I find the documentation of Format very difficult to read, but as I understand it:
1)  The format code does not have to be enclosed in brackets (hence the option to add them if you want)
2)  The Arg parameter must be enclosed in brackets - which happens inside the code

Unclear to me is what I mentioned above:
3) Dow the Arg have to be presented as a constant, or can it be the current value of a variable? Documentation is significantly silent on this, and the examples show only constant values.

Does anybody have a code example which shows the use of a variable as the value to be formatted? Or do I have to engage in some type-casting to force the compiler to treat it as a constant.

Thanks in advance,

Tony




wp

  • Hero Member
  • *****
  • Posts: 12866
Re: Formatting a numer right-justified with leading spaces
« Reply #8 on: May 26, 2025, 09:46:41 pm »
It doesn't do what I expected!

I have no idea what you expected.

I typed "input value" as "123" and "Format code" as "%d" - and received an error. This happens because the variable "inputValue" that you pass to the Format() instruction is always a string. Therefore you can only use formatstring containing the %s, %d will fail because it expects an integer. You cannot enter integers in an edit box - it always contains a string. If you need an integer you must convert it: inputInt = StrToInt(inputValue) (or you must use a special control which returns integers, such as a TSpinEdit).

Below  you'll find a modified version of my previous sample code which demonstrates that the Format() instruction does work with variables (well - otherwise it would be rather useless).

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. uses
  3.   SysUtils;
  4. var
  5.   s: String;
  6.   n, w: Integer;
  7. begin
  8.   n := 123;
  9.   s := 'abc';
  10.  
  11.   WriteLn('Format using an integer...');
  12.   WriteLn(Format('"%d"',   [n]));       // "   123"
  13.   WriteLn(Format('"%6d"',  [n]));       // "   123"
  14.   WriteLn(Format('"%-6d"', [n]));       // "123   "
  15.   WriteLn(Format('"%.6d"', [n]));       // "000123"
  16.   WriteLn;
  17.  
  18.   WriteLn('Format using a string...');
  19.   WriteLn(Format('"%s"',   [s]));     // "abc"
  20.   WriteLn(Format('"%6s"',  [s]));     // "   abc"
  21.   WriteLn(Format('"%-6s"', [s]));     // "abc   "
  22.   WriteLn(Format('"%.6s"', [s]));     // "abc"
  23.  
  24.   WriteLn;
  25.   WriteLn('Format using integer and string parameters...');
  26.   WriteLn(Format('s := "%s";  n := %d', [s, n]));   // s := "abc";  n := 123
  27.  
  28.   WriteLn;
  29.   WriteLn('You can even change the field width by a variable:');
  30.   w := 20;
  31.   WriteLn(Format('"%*d"', [w, n]));   // "                 123"  ( field width is 20 )
  32.   WriteLn(Format('"%-*d"', [w, n]));  // "123                 "  ( field width is 20 )
  33.   WriteLn(Format('"%.*d"', [w, n]));  // "00000000000000000123"  ( field width is 20 )
  34.   ReadLn;
  35. end.
« Last Edit: May 26, 2025, 09:54:22 pm by wp »

tfurnivall

  • New Member
  • *
  • Posts: 43
Re: Formatting a numer right-justified with leading spaces
« Reply #9 on: May 26, 2025, 10:37:47 pm »
Thanks, wp.

I knew it was something like that. Sometimes one gets so close to the ground tracking down a solution, that one forgets the inherent strong typing of Pascal!

Substituting an integer variable (IVInteger) and using strtoint() made everything clear.

My mind is a little less foggy - here's hoping that the process of elucidation will continue without too much headache!

Thanks, again

Tony

 

TinyPortal © 2005-2018