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

发布于 2024-10-07 13:24:53 字数 396 浏览 4 评论 0原文

我正在尝试为一周中的几天创建自定义数据类型,但我无法让它编写它。编译器错误是这样说的:

[错误]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 中。

I'm trying to make a custom data type for days of the week but I can't get it to write it. The compiler error says this:

[Error] hours.dpr(28): Illegal type in Write/Writeln statement

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.

It's in Delphi 7 on Windows.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

风追烟花雨 2024-10-14 13:24:53

您不需要为此编写汇编程序; 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

问候。

You don't need to write Assembler for this; TypInfo include all that you need for do this (get the string associated to an enumerated value).

This code:

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.

And this is the output:

alt text

Regards.

尾戒 2024-10-14 13:24:53

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.

Tom, Writeln does not support a Enum as parameter. you must call to the Ordfunction to get the ordinal representation. if you wanna show the names of your TypeDay you can write a code like this.

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.
森末i 2024-10-14 13:24:53

您可以使用 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 是否在范围内。

You can use RTTI to write the enumerate names.

Here is an optimized function I wrote some time ago:

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.

But be warned that this version doesn't check for that aIndex to be in range.

深海夜未眠 2024-10-14 13:24:53

枚举不是字符串,因此您需要将它们转换。
对于转换,您可以使用 Delphi TypInfo 单元中的 GetEnumName 函数作为 在 delphi.about.com 进行了解释。

——杰罗恩

Enumerations are not strings, so you need to convert them.
For conversion, you can use the GetEnumName function from the Delphi TypInfo unit as explained at delphi.about.com.

--jeroen

提赋 2024-10-14 13:24:53

有趣的是,我可以在 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. 

Interestingly enough, I'm able to use readLn with enum types in FPC (Lazarus), but will throw the same error (illegal type) as mentioned above in 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. 

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文