Erlang code to list all IP addresses
First of all your variable IPAddress is misnamed. It sounds as if it contained a single IP address, but in fact it contains a list of multiple triples, where each one does not only contain an IP address, but also the corresponding broadcast address and netmask. You should probably call it something like IPTriples.

If you look at your code it's basically doing three things:


Filtering out localhost
Replacing each ip address with a string representation
Concatenating the thus created list of strings, separating them with spaces.


For each of these 3 steps there's already an erlang function, which can be used to do it:


lists:filter which takes a predicate and a list and returns a list only containing elements that match this predicate.
lists:map which takes a function and a list and returns a list containing the result of the function for each element.
string:join which takes a list of strings and a separator and returns a string with each item in the list separated by the separator.


Usually it it is good style to reuse existing functionality as much as possible instead of reimplementing it. So using these functions, your get_ip_address_string can be rewritten to something like this:

get_ip_address_string() -&gt;
    {ok, IPTriples} = inet:getif(),
    FilteredIPTriples = lists:filter(fun is_not_localhost/1), IPTriples),
    IPAddresses = lists:map(fun ip_triple_to_string/1, FilteredIPTriples),
    string:join(IPAddresses, " ").

is_not_localhost({{127,0,0,1}, _Broadcast, _Mask}) -&gt; false;
is_not_localhost({_IP, _Broadcast, _Mask})         -&gt; true.

ip_triple_to_string({{Oct1, Oct2, Oct3, Oct4}, _Broadcast, _Mask}) -&gt;
    io_lib:format("~b.~b.~b.~b", [Oct1, Oct2, Oct3, Oct4]).


Note that this has also the benefit that the logic for filtering out localhost, the logic for turning the IP addresses into strings and the logic for building the result string from that are now no longer intertwined, which should make the code more manageable.