How to format a number with padding in Erlang

2019-01-15 12:18发布

问题:

I need to pad the output of an integer to a given length.

For example, with a length of 4 digits, the output of the integer 4 is "0004" instead of "4". How can I do this in Erlang?

回答1:

adding a bit of explanation to Zed's answer:

Erlang Format specification is: ~F.P.PadModC.

"~4..0B~n" translates to:

 ~F. = ~4.  (Field width of 4)
  P. =   .  (no Precision specified)
Pad  =  0   (Pad with zeroes)
Mod  =      (no control sequence Modifier specified)
  C  =  B   (Control sequence B = integer in default base 10)

and ~n is new line.



回答2:

io:format("~4..0B~n", [Num]).



回答3:

string:right(integer_to_list(4), 4, $0).



回答4:

The problem with io:format is that if your integer doesn't fit, you get asterisks:

> io:format("~4..0B~n", [1234]).
1234
> io:format("~4..0B~n", [12345]).
****

The problem with string:right is that it throws away the characters that don't fit:

> string:right(integer_to_list(1234), 4, $0).
"1234"
> string:right(integer_to_list(12345), 4, $0).
"2345"

I haven't found a library module that behaves as I would expect (i.e. print my number even if it doesn't fit into the padding), so I wrote my own formatting function:

%%------------------------------------------------------------------------------
%% @doc Format an integer with a padding of zeroes
%% @end
%%------------------------------------------------------------------------------
-spec format_with_padding(Number :: integer(),
                          Padding :: integer()) -> iodata().
format_with_padding(Number, Padding) when Number < 0 ->
    [$- | format_with_padding(-Number, Padding - 1)];
format_with_padding(Number, Padding) ->
    NumberStr = integer_to_list(Number),
    ZeroesNeeded = max(Padding - length(NumberStr), 0),
    [lists:duplicate(ZeroesNeeded, $0), NumberStr].

(You can use iolist_to_binary/1 to convert the result to binary, or you can use lists:flatten(io_lib:format("~s", [Result])) to convert it to a list.)