62

I know strings in Erlang can be costly to use. So how do I convert "5"to 5?

Is there anything like io:format("~p",[5]) that would return a formatted string instead of printing to a stream?

2240
  • 1,547
  • 2
  • 12
  • 30
collapsinghrung
  • 855
  • 1
  • 6
  • 7
  • 1
    Avoided at all costs? Where did you get that idea? There are some performance concerns and other annoyances, but they are still a core data type and the default choice for strings. – cthulahoops Feb 26 '09 at 00:48
  • 1
    I speak with tongue in cheek. If I firmly believed that you should never use them, I wouldn't have asked this question. On the other hand, describing them as a "core data type" might be stretching things a little far, in my view. – collapsinghrung Feb 26 '09 at 03:28
  • 1
    string in erlang is a list. it is core data type. the same as binary or atom. – Worker Dec 18 '12 at 16:16

5 Answers5

157

There's also integer_to_list/1, which does exactly what you want, without the ugliness.

womble
  • 12,033
  • 5
  • 52
  • 66
31

A string is a list:

9> integer_to_list(123).  
"123"
Thomas
  • 4,208
  • 2
  • 29
  • 31
16

The following is probably not the neatest way, but it works:

1> lists:flatten(io_lib:format("~p", [35365])).
"35365"

EDIT: I've found that the following function comes in useful:

%% string_format/2
%% Like io:format except it returns the evaluated string rather than write
%% it to standard output.
%% Parameters:
%%   1. format string similar to that used by io:format.
%%   2. list of values to supply to format string.
%% Returns:
%%   Formatted string.
string_format(Pattern, Values) ->
    lists:flatten(io_lib:format(Pattern, Values)).

EDIT 2 (in response to comments): the above function came from a small program I wrote a while back to learn Erlang. I was looking for a string-formatting function and found the behaviour of io_lib:format/2 within erl counter-intuitive, for example:

1> io_lib:format("2 + 2 = ~p", [2+2]).
[50,32,43,32,50,32,61,32,"4"]

At the time, I was unaware of the 'auto-flattening' behaviour of output devices mentioned by @archaelus and so concluded that the above behaviour wasn't what I wanted.

This evening, I went back to this program and replaced calls to the string_format function above with io_lib:format. The only problems this caused were a few EUnit tests that failed because they were expecting a flattened string. These were easily fixed.

I agree with @gleber and @womble that using this function is overkill for converting an integer to a string. If that's all you need, use integer_to_list/1. KISS!

Luke Woodward
  • 63,336
  • 16
  • 89
  • 104
  • 27
    There is absolutely no need to use `io_lib:format/2` for this simple task. `integer_to_list/1` is enough. – gleber Feb 25 '09 at 22:56
  • 2
    Also, flattening the resulting iolist is normally wasteful. Sockets/Ports/Files/IoDevices all flatten on output, so flattening yourself is redundant. – archaelus Feb 25 '09 at 23:04
  • 1
    integer_to_list/1 is enough for the headlined question, but this does neatly answer my "can you produce formatted strings with interpolated numbers" subquestion... – collapsinghrung Feb 25 '09 at 23:07
  • 3
    It's a pity that this is the selected answer because [womble](http://stackoverflow.com/a/588248/191191)'s is the proper answer. – Rodrigue Apr 09 '13 at 17:21
4

As an aside if you ever need to deal with the string representation of floats you should look at the work that Bob Ippolito has done on mochinum.

Gordon Guthrie
  • 6,252
  • 2
  • 27
  • 52
2

lists:concat([Number]). also works.

Michael Neale
  • 19,248
  • 19
  • 77
  • 109