使用io_lib:format实现~p和~w格式的混合

时间:2017-10-23 09:32:41

标签: erlang

假设我有一个任意格式的字符串和som对应的数据,并且数据包含带有字符串元素的元组。作为(缩短)的例子:

Format = "~p~n",
Data = {"ABC"},

出于特定目的,我想打印相同的输出,但只能在一行上打印。我想实现与" ~p"相同的格式。 (即。Data应打印为{"ABC"}而不是{[65,66,67]}。这可能吗?

我想我可以分三步完成:

  • io_lib:format~p
  • 循环生成字符串并删除所有新行字符
  • 正则表达式用单个空格替换多个连续空格的所有序列

但这种做法似乎乏味而且效率低下。有没有更好的方法来使用OTP函数来做到这一点?

2 个答案:

答案 0 :(得分:2)

如果您知道输出永远不会超过百万个字符,则可以指定~p说明符的输出宽度:

io:format("~1000000p", [Data]).

答案 1 :(得分:2)

正如legoscia指出的那样,io:format/2试图在漂亮的打印元素和行长度方面保持礼貌,以及您可以通过格式字符串参数调整每个元素的内容。请注意,如果您使用格式控制序列,这意味着格式本身就是您控制输出每个元素的长度的位置。

允许您声明行的总长度(与每个元素相对)的替代方法是io_lib:print/4。我倾向于发现这个特殊的功能对日志消息格式化更有用:

1> T = {"Some really long things","are in this tuple","but it won't really matter","because they will be in line"}.
{"Some really long things","are in this tuple",
 "but it won't really matter","because they will be in line"}
2> io:format("~tp~n", [T]).
{"Some really long things","are in this tuple","but it won't really matter",
 "because they will be in line"}
3> S = io_lib:print(T, 1, 1000, -1).
[123,
 ["\"Some really long things\"",44,"\"are in this tuple\"",
  44,"\"but it won't really matter\"",44,
  "\"because they will be in line\""],
 125]
4> lists:flatten(S).
"{\"Some really long things\",\"are in this tuple\",\"but it won't really matter\",\"because they will be in line\"}"
5> io:format("~ts~n", [S]).
{"Some really long things","are in this tuple","but it won't really matter","because they will be in line"}
ok

仔细阅读ioio_lib的文档。实际上有很多功能包装在那里随时出现。

请记住,如果目标是控制终端本身,您还可以通过打印单个字符并使用ASCII控制序列来完成相当多的有趣工作。如果您要解决的问题是构建基于文本的界面或类似的东西,使用io:put_chars/1的逐个字符或每个blit屏幕更新字符串输出可以是一个强大的工具。