首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >有没有办法在Ada中格式化文本输出

有没有办法在Ada中格式化文本输出
EN

Stack Overflow用户
提问于 2011-05-17 22:19:26
回答 6查看 10.5K关注 0票数 10

有没有一种方法可以格式化输出的字符串?我正在尝试获得以下输出的美观视图

代码语言:javascript
运行
复制
1: Ashley | 01033438392 | Wellington, New Zealand | 1987- 4-14  
2: Aloha | 01087651234 | Hawaii, United States of America | 1988- 9-23
3: Jack | 01082840184 | Beijing, China | 1989- 6-19

如果我用C语言编程,我会这样做

代码语言:javascript
运行
复制
printf("%10s | %11s | %20s | %4d-%2d-%2d\n",name,phone,address,year,month,day);

在Ada 05中可以进行这种格式设置吗?

PS请忽略姓名、电话号码、地址和生日。我在30秒内就编好了……

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-05-18 02:11:40

这是可以做到的,但机制有点笨拙,而且相当冗长。

我通常会做的是编写单独的过程来处理更复杂的输出,例如日期,并将其与字符串处理的其余部分一起使用以保持清晰。

代码语言:javascript
运行
复制
package Integer_IO is new Ada.Text_IO.Integer_IO (Integer);

procedure Output_Date ( Day : in Integer; Month: in Integer; Year: in Integer) is 
begin  
  Integer_IO.Put(Item => Day, Width => 2); 
  Text_IO.Put("-");
  Integer_IO.Put(Item => Month, Width => 2); 
  Text_IO.Put("-");
  Integer_IO.Put(Item => Year, Width => 4);
end Output_Date;

procedure Output_String ( Item : in String; 
                          Width : in Integer; 
                          Separator : in String := "|";
                          Truncate : Boolean := False) is 
  Field_Index : Integer := Text_IO.Col;
begin 
  if Item'length > Width and Truncate then 
    Text_IO.Put(Item(1..Width) & Separator);
  else 
    Text_IO.Put(Item) & Separator;
  end if;

  Text_IO.Set_Col ( Field_Index + Width + 1 );
end Output_String;

这将强制固定长度字段,这将可选地允许截断长字符串,或者将后续条目移动到下一行。Set_Col将为下一次写入设置行位置,如果当前写入位置已经超过请求的位置,则可能会将其放在下一行上。

我把字符串截断放在这里是为了使用数组切片和Text_IO的输出操作,但我通常不喜欢缺省截断,因为允许字符串超出请求的宽度或在下一行缩进会使格式错误更加明显。

因此,根据上面的代码,打印出类似于第一行的内容可能如下所示:

代码语言:javascript
运行
复制
Name  : String  := "Ashley"
Phone : String  := "01033438392"
Address: String := "Wellington, New Zealand"

Day    : Integer := 14;
Month : Integer  := 4;
Year   : Integer := 1987;

Output_String(Item=> Name,    Width => 10);
Output_String(Item=> Phone,   Width => 11);
Output_String(Item=> Address, Width => 20);
Output_Date(Day,Month,Year);

Ada中的Text IO通常很麻烦,但通常具有使您正在做的事情相对清晰的优点。

票数 8
EN

Stack Overflow用户

发布于 2011-05-18 03:32:53

请注意,在如今的C++中,printf()正处于被贬低的边缘,支持使用带有流格式化程序的流。它很方便,但非常不安全(至少在两种意义上)。如今,开发人员被鼓励使用C++ streams (及其分类的操纵器)来代替。

在Ada中,您可以使用字符串连接运算符&以与C++ streams非常相似的方式操作字符串,而C++人员使用流插入运算符(<<)。在某些方面,Ada的方法更好,因为您可以嵌套连接表达式,而流插入表达式无法做到这一点。

这里的问题是,像setfill()hexsetw()这样的C++格式化程序没有任何方便的等价物。确实应该有,而且(hex除外)自己编写它们并不难,但现在它们还不存在。

例如,setw()/setfill()等效项如下所示:

代码语言:javascript
运行
复制
Fill_Char : Character := ' ';

function Set_Fill (New_Fill : Character) return String is
begin
    Fill_Char := New_Fill;
    return "";
end Set_Fill;

--// Dumb tail-recursive implementation. 
function Set_Width(Source : in String; Width : in Positive) return String is
begin
    if Width <= Source'length then --'
        return Source;
    else 
        return Fill_Char & Set_Width(Source, Width - 1);
    end if;
end Set_Width;

Unfilled_String : constant String := "123456";
Filled_String : constant String := Set_Width(Unfilled_String & Set_Fill('0'), 8);
--// The above string should end up being "00123456"

如果你真的想要一个printf()接口,printf()当然可以从Ada中调用。您必须担心在Ada的大小字符串和C的nul终止字符串之间的转换,但这就是Ada.Interfaces.C.Strings的作用所在。

票数 4
EN

Stack Overflow用户

发布于 2015-05-24 21:09:55

对于这种特殊的格式设置,有一些辅助工具。

Ada.Text_IO.Integer_IO

代码语言:javascript
运行
复制
procedure Put(Item : in Num; Width : in Field := Default_Width; Base : in Number_Base := Default_Base);

Item右对齐并将空白字符作为填充的字段放入。其中Width是字段宽度,Base是10作为默认值。

Ada.Strings.Fixed

代码语言:javascript
运行
复制
function Head (Source : in String; Count : in Natural; Pad : in Character := Space) return String;
function Tail (Source : in String; Count : in Natural; Pad : in Character := Space) return String;

返回带格式的字符串。其中Count是字段宽度,Pad是字段的填充值。Head将字符串左对齐。Tail将字符串向右对齐。

让列宽为8个字符,并使用破折号作为填充符。

代码语言:javascript
运行
复制
Put_Line (Head ("Ashley", 8, '-'));
Put_Line (Head ("Aloha", 8, '-'));
Put_Line (Head ("Jack", 8, '-'));
Put_Line (Tail ("Ashley", 8, '-'));
Put_Line (Tail ("Aloha", 8, '-'));
Put_Line (Tail ("Jack", 8, '-'));

输出

代码语言:javascript
运行
复制
Ashley--
Aloha---
Jack----
--Ashley
---Aloha
----Jack

Attribute discrete_type'Width

返回离散类型需要表示为文本的长度。

示例

代码语言:javascript
运行
复制
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Calendar; use Ada.Calendar;

procedure Test is

   subtype Index is Positive range 95 .. 1223;

   procedure Put_Line ( I : in out Index; Name : String; Phone : Natural; Address : String; T : in out Time ) is
   begin
      Put (I, Index'Width);
      Put (": ");
      Put (Head (Name, 10, ' '));
      Put (" | ");
      Put (Tail (Phone'Img (Phone'Img'First + 1 .. Phone'Img'Last), 13, '0'));
      Put (" | ");
      Put (Head (Address, 20, ' '));
      Put (Year (T), Year_Number'Width);
      Put ("-");
      Put (Month (T), Month_Number'Width);
      Put ("-");
      Put (Day (T), Day_Number'Width);
      I := Positive'Succ (I);
      T := T + Duration (60 * 60 * 24 * 3);
      New_Line;
   end;

   I : Index := Index'First;
   Now : Time := Clock;
begin

   Put_Line (I, "Ashley", 1033438392, "Wellington, New Zealand", Now);
   Put_Line (I, "Aloha", 01087651234, "Hawaii, United States of America", Now);
   Put_Line (I, "Jack", 01082840184, "Beijing, China", Now);
   I := Index'Last - 3;
   Put_Line (I,"Ashley", 1033438392, "Wellington, New Zealand", Now);
   Put_Line (I,"Aloha", 01087651234, "Hawaii, United States of America", Now);
   Put_Line (I,"Jack", 01082840184, "Beijing, China", Now);

end;

输出

代码语言:javascript
运行
复制
   95: Ashley     | 0001033438392 | Wellington, New Zeal 2015-  5- 24
   96: Aloha      | 0001087651234 | Hawaii, United State 2015-  5- 27
   97: Jack       | 0001082840184 | Beijing, China       2015-  5- 30
 1220: Ashley     | 0001033438392 | Wellington, New Zeal 2015-  6-  2
 1221: Aloha      | 0001087651234 | Hawaii, United State 2015-  6-  5
 1222: Jack       | 0001082840184 | Beijing, China       2015-  6-  8

我建议为电话号码创建一个类型,我不知道它应该是字符串还是带有标题零的数字,我猜电话号码可以有不同的长度。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6032210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档