如何将WriteLn与枚举类型一起使用?

时间:2010-12-16 09:11:34

标签: delphi delphi-7 pascal

我正在尝试为一周中的几天制作自定义数据类型,但我无法写它。编译器错误说明了这一点:

  

[Error] hours.dpr(28):Write / Writeln语句中的非法类型

program hours;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TypeDay = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);

var day: TypeDay;

begin
     for day := Sun to Sat do
     begin
         writeln(day);
     end;
end.

在Windows上的Delphi 7中。

5 个答案:

答案 0 :(得分:17)

您不需要为此编写汇编程序; TypInfo包含执行此操作所需的所有内容(获取与枚举值关联的字符串)。

此代码:

program hours;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  TypInfo;

type
  TypeDay = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);

var
  day: TypeDay;
  Str:String;

begin
     for day := Sun to Sat do begin
        Str := GetEnumName(TypeInfo(TypeDay),ord(day));
         writeln(Str);
     end;
end.

这是输出:

alt text

的问候。

答案 1 :(得分:11)

Tom,Writeln不支持Enum作为参数。你必须调用Ord函数来获得序数表示。如果你想显示你的TypeDay的名字,你可以写这样的代码。

program hours;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TypeDay     = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);
const
  TypeDayStr  : Array[TypeDay] of string = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');

var day: TypeDay;

begin
     for day := Sun to Sat do
       writeln( Ord(day));

     for day := Sun to Sat do
       writeln( TypeDayStr[day]);

     Readln;
end.

答案 2 :(得分:4)

您可以使用RTTI编写枚举名称。

这是我前段时间写的优化函数:

program hours;

{$APPTYPE CONSOLE}

uses
  SysUtils;

function GetEnumName(aTypeInfo: pointer; aIndex: integer): PShortString;
asm // get enumerate name from RTTI
    or edx,edx
    movzx ecx,byte ptr [eax+1] // +1=TTypeInfo.Name
    mov eax,[eax+ecx+1+9+1] //BaseType
    mov eax,[eax]
    movzx ecx,byte ptr [eax+1]
    lea eax,[eax+ecx+1+9+4+1] // eax=EnumType.BaseType^.EnumType.NameList
    jz @0
@1: movzx ecx,byte ptr [eax]
    dec edx
    lea eax,eax+ecx+1 // next short string
    jnz @1
@0:
end;

type
  TypeDay = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);

var day: TypeDay;

begin
     for day := Sun to Sat do
     begin
         writeln(GetEnumName(TypeInfo(TypeDay),ord(day))^);
     end;
end.

但请注意,此版本不会检查aIndex是否在范围内。

答案 3 :(得分:2)

枚举不是字符串,因此您需要转换它们 对于转换,您可以使用Delphi GetEnumName单元中的TypInfo函数作为explained at delphi.about.com

- 的Jeroen

答案 4 :(得分:0)

有趣的是,我可以在 FPC (Lazarus) 中使用带有枚举类型的 readLn,但会抛出与上面在 Delphi、Oxygene、PascalABC.Net 中提到的相同的错误(非法类型)...


    type
        beverage = (coffee, tea, milk, water, coke, limejuice);
    
    var
        drink : beverage;
    
    begin
         writeLn('Which drink do you want? ');
         writeLn('Here are the choices: coffee, tea, milk, water, coke, limejuice ');
         readLn(drink);
         writeLn('So you would like to drink ', drink, '.');
         readLn
    end.