How to print a number with a thousand separator as spaces in Pascal

1 Answer

0 votes
program ThousandSeparatorSpaces;

{$mode objfpc}{$H+}

uses
  SysUtils;

{
    Program: Print numbers with a thousand separator as spaces in Free Pascal.

    Architecture notes:
    -------------------
    - Free Pascal does not provide built-in thousand-separator formatting.
    - We implement a manual formatter:
        * Convert the number to a string.
        * Handle negative numbers cleanly.
        * Insert spaces every three digits from the left.
    - The function is modular, reusable, and efficient.

    Performance notes:
    ------------------
    - O(n) time where n is the number of digits.
    - Memory usage is minimal; only small strings are created.
    - No external libraries; uses only standard Free Pascal features.

    Pitfalls:
    ---------
    - Must preserve the minus sign for negative numbers.
    - Must ensure correct grouping even for very large integers.
    - Avoid formatting floating-point values unless converted to integers first.

    Security notes:
    ---------------
    - No external input parsing; safe for demonstration.
    - Avoid printing sensitive values in real systems.

    Tests:
    ------
    - Positive numbers
    - Negative numbers
    - Zero
    - Very large integers
}


function FormatWithSpaces(n: Int64): string;
var
    s, digits: string;
    isNegative: boolean;
    lenDigits, firstGroup, i, pos: integer;
begin
    s := IntToStr(n);
    isNegative := (s[1] = '-');

    if isNegative then
        digits := Copy(s, 2, Length(s) - 1)
    else
        digits := s;

    lenDigits := Length(digits);

    { Determine how many digits before the first space }
    firstGroup := lenDigits mod 3;
    if firstGroup = 0 then
        firstGroup := 3;

    Result := '';

    { Add minus sign if needed }
    if isNegative then
        Result := '-';

    { Add first group }
    Result := Result + Copy(digits, 1, firstGroup);

    { Add remaining groups of 3 digits }
    pos := firstGroup + 1;
    while pos <= lenDigits do
    begin
        Result := Result + ' ' + Copy(digits, pos, 3);
        pos := pos + 3;
    end;
end;


procedure RunTests;
var
    tests: array[1..6] of Int64;
    i: integer;
begin
    tests[1] := 0;
    tests[2] := 42;
    tests[3] := 1234;
    tests[4] := 987654321;
    tests[5] := -1234567;
    tests[6] := 1000000000000000000;  { 10^18 }

    Writeln('Running test cases:');
    Writeln;

    for i := 1 to Length(tests) do
    begin
        Writeln('Original:  ', tests[i]);
        Writeln('Formatted: ', FormatWithSpaces(tests[i]));
        Writeln;
    end;
end;


begin
    RunTests;
end.



{
run:

Running test cases:

Original:  0
Formatted: 0

Original:  42
Formatted: 42

Original:  1234
Formatted: 1 234

Original:  987654321
Formatted: 987 654 321

Original:  -1234567
Formatted: -1 234 567

Original:  1000000000000000000
Formatted: 1 000 000 000 000 000 000

}

 



answered Sep 22 by avibootz
...