Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 枚举字符串_Delphi_String_Enumeration - Fatal编程技术网

Delphi 枚举字符串

Delphi 枚举字符串,delphi,string,enumeration,Delphi,String,Enumeration,我有一个状态,它以一个设定长度的字符串存储在文件或数据库中 我想列举可能的状态' Type TStatus = (fsNormal = Ord('N'),fsEditedOnScreen = Ord('O'), fsMissing = Ord('M'),fsEstimated = Ord('E'),fsSuspect = Ord('s'), fsSuspectFromOnScreen = Ord('o'),fsSuspectMiss

我有一个状态,它以一个设定长度的字符串存储在文件或数据库中

我想列举可能的状态'

Type TStatus = (fsNormal = Ord('N'),fsEditedOnScreen = Ord('O'),
                fsMissing = Ord('M'),fsEstimated = Ord('E'),fsSuspect = Ord('s'),
                fsSuspectFromOnScreen = Ord('o'),fsSuspectMissing = Ord('m'),
                fsSuspectEstimated = Ord('e'));
我有以下类型来定义可能的状态'

Type TStatus = (fsNormal = Ord('N'),fsEditedOnScreen = Ord('O'),
                fsMissing = Ord('M'),fsEstimated = Ord('E'),fsSuspect = Ord('s'),
                fsSuspectFromOnScreen = Ord('o'),fsSuspectMissing = Ord('m'),
                fsSuspectEstimated = Ord('e'));
首先,这真的是个好主意吗?或者我应该有一个单独的常量数组来存储字符转换?这意味着不止一个地方需要更新

现在,将字符串转换为状态数组我有以下内容,但是如何在不循环枚举的情况下检查字符是否有效

Function StrToStatus(Value : String):TStatusArray;
var
    i: Integer;
begin
    if Trim(Value) = '' then
    begin
        SetLength(Result,0);
        Exit;
    end;
    SetLength(Result,Length(Value));
    for i := 1 to Length(Value) do
    begin
        Result[i] := TStatus(Value[i]); // I don't think this line is safe.
    end;
end;
经过一些测试后,它确认可疑线路是安全的(不会崩溃!),但只是添加了(越界)值,然后需要过滤掉

Function StrToStatus(Value : String):TStatusArray;
var
    i: Integer;
begin
    if Trim(Value) = '' then
    begin
        SetLength(Result,0);
        Exit;
    end;
    SetLength(Result,Length(Value));
    for i := 1 to Length(Value) do
    begin
        Result[i-1] := TStatus(Value[i]);
    end;
    for i := 0 to Length(Result) - 1 do
    begin
        case Result[i] of
            fsNormal: ;
            fsEditedOnScreen: ;
            fsMissing: ;
            fsEstimated: ;
            fsSuspect: ;
            fsSuspectFromOnScreen: ;
            fsSuspectMissing: ;
            fsSuspectEstimated: ;
            else
                Result [i] := fsNormal;
        end;
    end;
end;
这允许所有状态及其相对字符值位于一个位置,并防止字符串中每个字符的每个状态循环。(所以在我看来至少应该快一点)

好的,这应该可以再次转换回来

Function StatusToStr(Value : TStatusArray):String;
var
  i: Integer;
begin
    for i := 0 to Length(Value) - 1 do
        Result := Result + Chr(Ord(Value[i]))
end;

我首先使用的是Delphi 2007,我想知道为什么要将其保存为字符串而不是整数

你做这件事的方式,唯一正确的方式就是有一个案例条件

function CharToStatus(AChar : Char):TStatus;
begin
  case AChar of
    'N' : Result := fsNormal;
    'O' : Result := fsEditedOnScreen;
    'M' : Result := fsMissing;
    'E' : Result := fsEstimated;
    's' : Result := fsSuspect;
    'o' : Result := fsSuspectFromOnScreen;
    'm' : Result := fsSuspectMissing;
    'e' : Result := fsSuspectEstimated;
  else
    //Manage error;
  end;
end;

function StatusToChar(AStatus : TStatus) : char;
begin
  Result := Char(AStatus);
end;
[Low(TStatus)]…High(TStatus)]中的表达式
x在这种情况下不起作用。
原因是低(TStatus)=“E”,高(TStatus)=“s”。介于两者之间的任何内容都将被视为有效。(即“Z”处于[低(TStatus)]…高(TStatus)])

[Low(TStatus)]…High(TStatus)]中的表达式
x仅适用于声明中没有“洞”的类型。(与那些没有显式值的元素类似,其中第一个元素为0,第二个元素为1,第三个元素为2…等等)

//编辑

好的。。再进一步思考这个问题,我不明白你为什么不喜欢常量数组方法。。。像这样的事情会好得多

type
  TStatus = (fsNormal, fsEditedOnScreen,
                fsMissing,fsEstimated,fsSuspect,
                fsSuspectFromOnScreen,fsSuspectMissing ,
                fsSuspectEstimated);
const
  StatusValue : Array[TStatus] of Char = ('N','O','M','E','s','o','m','e');

function StatusValueToTStatus(C : Char) : TStatus;
var I : Integer;
begin
  for I := Low(StatusValue) to High(StatusValue)  do
  begin
    if StatusValue = C then
    begin
      Result := TStatus(I);
      EXIT;
    end;
  end;
  //Not found, Manage errors
end;

如果我理解正确,我会将数组替换为集合,并使用不带显式值的枚举,如下所示:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TStatus = (fsNormal, fsEditedOnScreen, fsMissing, fsEstimated, fsSuspect,
    fsSuspectFromOnScreen, fsSuspectMissing, fsSuspectEstimated);
  TStatusSet = set of TStatus;

const
  cStatusChars: array[TStatus] of Char = ('N', 'O', 'M', 'E', 's', 'o', 'm', 'e');

function CharToStatus(AChar: Char; out AStatus: TStatus): Boolean;
var
  st: TStatus;
begin
  for st := Low(TStatus) to High(TStatus) do
    if cStatusChars[st] = AChar then
    begin
      AStatus := st;
      Result := True;
      Exit;
    end;
  Result := False;
end;

function StrToStatus(const Value: string): TStatusSet;
var
  i: Integer;
  st: TStatus;
begin
  Result := [];
  for i := 1 to Length(Value) do
    if CharToStatus(Value[i], st) then
      Include(Result, st);
end;

function StatusToStr(const Value: TStatusSet): string;
var
  st: TStatus;
begin
  for st in Value do
    Result := Result + cStatusChars[st];
end;

var
  StatusSet: TStatusSet;
begin
  StatusSet := StrToStatus('EmO');
  Writeln(StatusToStr(StatusSet));
  Readln;
end.

它保存为字符串,作为旧系统的一部分。我没有选择const方法的原因很简单,因为我可以看到其他开发人员在添加新状态时有点粗心大意,从而破坏了这种方法。如果他们在添加新的枚举值后不调整数组长度,代码将不会编译。我需要的结果是数组而不是集合(字符串表示多个值的不同状态,每个值只能有一个状态)。除此之外,我应该考虑额外循环的性能问题吗?额外循环指的是ChartStatus中的一个?您可以通过构造查找数组
数组[Char]来替换它在你第一次使用StrToStatus之前,我不知道这是否会加快速度。