"Type mismatch" Inno Setup Unicode 版本的 Pascal 脚本中的 "set of char" 错误
"Type mismatch" error on "set of char" in Pascal Script of the Inno Setup Unicode version
我有一个适用于 Inno Setup 的可用 Pascal 脚本,但最近我们 运行 遇到了 Unicode 字符的问题。在将 Inno Setup 更改为 Unicode 版本后,我们在现有脚本中遇到了错误。而且这个错误太笼统了 - "Type mismatch" 对于某些行。由于我们的主脚本由包含的许多其他脚本组成,我不确定该行是否正确,它指向下面的这个函数,并与 Set of Char
行。
在查看 Inno Setup 文档后,我发现 Unicode 版本在某些方面更加严格,并且在 ANSI 字符串处理方面也有一些变化(可能 Char
)。
function IsValidName(Name: String):String;
var
Valid_Ch: Set of Char;
Location: Integer;
begin
Valid_Ch := ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '_', '-'];
Result := '';
for Location := 1 to Length(Name) do
begin
if Name[Location] in Valid_Ch then
begin
Result := Result + Name[Location];
end
else
begin
Result := Result + '_';
end;
end;
end;
我觉得这一切都很好,但这是我第一次接触 Pascal。如果有经验的人可以帮助我解决这个问题,我将不胜感激。
谢谢!
在 Pascal(脚本)中,set
只能包含 256 (2^8) 个值。在 Unicode Inno Setup 中,Char
是 2 字节的,因此它可以包含超过 256 个不同的值。所以你不能再将它与 set
一起使用了。
您有以下选择:
在您的例子中,由于集合实际上是常量,您可以在 if
表达式中使用常量集。有趣的是,这甚至在 Unicode 版本中也有效(可能有一些内置的 hack 允许这个例外)。
function IsValidName(Name: string): string;
var
Location: Integer;
begin
Result := Name;
for Location := 1 to Length(Name) do
begin
if not (Name[Location] in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '_', '-']) then
begin
Result[Location] := '_';
end;
end;
end;
如果您需要集合可变(不是您的情况):
- 使用
Byte
并在 Char
和 Byte
之间进行转换,并将所有字符显式替换为 Ord() > 255
或使用 string
而不是 set
。有关示例,请参见下文。
function IsValidName(Name: string): string;
var
Valid_Ch: string;
Location: Integer;
begin
Valid_Ch := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_-';
Result := Name;
for Location := 1 to Length(Result) do
begin
if Pos(Result[Location], Valid_Ch) = 0 then
begin
Result[Location] := '_';
end;
end;
end;
另请注意,逐个字符地附加字符串可能效率很低。就地替换字符(如上面两个示例所示)。
我有一个适用于 Inno Setup 的可用 Pascal 脚本,但最近我们 运行 遇到了 Unicode 字符的问题。在将 Inno Setup 更改为 Unicode 版本后,我们在现有脚本中遇到了错误。而且这个错误太笼统了 - "Type mismatch" 对于某些行。由于我们的主脚本由包含的许多其他脚本组成,我不确定该行是否正确,它指向下面的这个函数,并与 Set of Char
行。
在查看 Inno Setup 文档后,我发现 Unicode 版本在某些方面更加严格,并且在 ANSI 字符串处理方面也有一些变化(可能 Char
)。
function IsValidName(Name: String):String;
var
Valid_Ch: Set of Char;
Location: Integer;
begin
Valid_Ch := ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '_', '-'];
Result := '';
for Location := 1 to Length(Name) do
begin
if Name[Location] in Valid_Ch then
begin
Result := Result + Name[Location];
end
else
begin
Result := Result + '_';
end;
end;
end;
我觉得这一切都很好,但这是我第一次接触 Pascal。如果有经验的人可以帮助我解决这个问题,我将不胜感激。 谢谢!
在 Pascal(脚本)中,set
只能包含 256 (2^8) 个值。在 Unicode Inno Setup 中,Char
是 2 字节的,因此它可以包含超过 256 个不同的值。所以你不能再将它与 set
一起使用了。
您有以下选择:
在您的例子中,由于集合实际上是常量,您可以在
if
表达式中使用常量集。有趣的是,这甚至在 Unicode 版本中也有效(可能有一些内置的 hack 允许这个例外)。function IsValidName(Name: string): string; var Location: Integer; begin Result := Name; for Location := 1 to Length(Name) do begin if not (Name[Location] in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '_', '-']) then begin Result[Location] := '_'; end; end; end;
如果您需要集合可变(不是您的情况):
- 使用
Byte
并在Char
和Byte
之间进行转换,并将所有字符显式替换为Ord() > 255
或使用
string
而不是set
。有关示例,请参见下文。function IsValidName(Name: string): string; var Valid_Ch: string; Location: Integer; begin Valid_Ch := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_-'; Result := Name; for Location := 1 to Length(Result) do begin if Pos(Result[Location], Valid_Ch) = 0 then begin Result[Location] := '_'; end; end; end;
另请注意,逐个字符地附加字符串可能效率很低。就地替换字符(如上面两个示例所示)。