检查字符串是否可以在XE4及更高版本中安全地转换为AnsiString的最简单方法是什么?

时间:2014-06-22 14:12:10

标签: delphi unicode

在Delphi XE4及更高版本中,我们可能会写一些类似的东西:

function TestAnsiCompatible(const aStr: string): Boolean;
begin
end;
Delphi XE4中的

string声明为UnicodeString。它可能包含一个unicode字符串。

如果我们进行某种类型转换:

function TestAnsiCompatible(const aStr: string): Boolean;
var a: AnsiString;
begin
  a := aStr;
  Result := a = aStr;
end;

某些编译器警告应该提示:

[dcc32 Warning]: W1058 Implicit string cast with potential data loss from 'string' to 'AnsiString'
[dcc32 Warning]: W1057 Implicit string cast from 'AnsiString' to 'string'

是否有一种简单而简洁的方法来测试aStr是否与AnsiString完全兼容?或者我们将按字符检查字符:

function TestAnsiCompatible(const aStr: string): Boolean;
var C: Char;
begin
  Result := True;
  for C in aStr do begin
    if C > #127 then begin
      Result := False;
      Break;
    end;
  end;
end;

2 个答案:

答案 0 :(得分:6)

你所要做的就是输掉警告:

function TestAnsiCompatible(const aStr: string): Boolean;
var
  a: AnsiString;
begin
  a := AnsiString(aStr);
  Result := String(a) = aStr;
end;

可以简化为:

function TestAnsiCompatible(const aStr: string): Boolean;
begin
  Result := String(AnsiString(aStr)) = aStr;
end;

答案 1 :(得分:1)

我曾经检查过String(a) = AnsiString(a),直到我有一个用户将数据从一台PC传输到另一台PC,并且有不同的代码页。然后无法正确读回数据。然后我将“safe”的定义更改为“string is code page 1252”(因为这是我的大多数用户所在的区域)。然后在回读我的数据时,我知道我必须从代​​码页1252转换回字符串。

function StringIs1252(const S: UnicodeString): Boolean;
// returns True if a string is in codepage 1252 (Western European (Windows))
// Cyrillic is 1251
const
  WC_NO_BEST_FIT_CHARS = $00000400;
var
  UsedDefaultChar: BOOL;   // not Boolean!!
  Len: Integer;
begin
  if Length(S) = 0 then
    Exit(True);
  UsedDefaultChar := False;
  Len := WideCharToMultiByte(1252, WC_NO_BEST_FIT_CHARS, PWideChar(S), Length(S), nil, 0, nil, @UsedDefaultChar);
  if Len <> 0 then
    Result := not UsedDefaultchar
  else
    Result := False;
end;

但是如果你想检查你的字符串是否可以安全地转换为ansi - 完全独立于写或读时使用的代码页,那么你应该检查所有字符是否都在#0的范围内。# 127。