2010-11-21 8 views
16

he actualizado una aplicación de Delphi 2007 para Delphi 2010, todo fue bien, excepto una declaración que compila bien, pero no funcionaba, que es:CharInSet no funciona con letras que no sean inglesas?

If Edit1.Text[1] in ['S','س'] then 
    ShowMessage('Found') 
else 
    ShowMessage('Not Found') 

Sin embargo, sabía que en no, por lo que cambió a CharInSet

If CharinSet(Edit1.Text[1],['S','س']) then 
    ShowMessage('Found') 
else 
    ShowMessage('Not Found') 

pero nunca funcionó cuando la cadena es س, pero siempre funciona con S, yo tire la edt1.Text 1 con AnsiChar siempre no funciona letras árabes.

¿Estoy haciendo algo mal, o no funciona CharInSet ?, ¿o es un error en CharinSet?

ACTUALIZACIÓN:

mi gran amigo Issam Ali ha sugerido otra solución que ha funcionado bien, ya que:

If CharinSet(AnsiString(edt1.Text)[1],['S','س']) then 
+0

¿Qué tipo es 'edt1'? – dan04

+0

@ dan04, es TEdit, he cambiado el código para mostrar que es como edición en lugar de edt –

+3

El compilador emite la siguiente advertencia con su código CharInSet: [Advertencia DCC] Unit5.pas (30): W1061 Estrechando la constante WideChar (# $ 0633) a AnsiChar perdió información –

Respuesta

17

CharInSet es inútil para los caracteres anteriores 255. En su caso se debe utilizar

case C of 
    'S','س' : ShowMessage('Found'); 
    end; 
+0

Funcionó bien gracias, no pensé, porque pensé que tendría el mismo problema que en. –

1

se ha marcado la codificación del archivo fuente a UTF-8 (clic derecho para abrir el Menú de contexto)? (El valor por defecto es ANSI IIRC, que no iba a funcionar.)

+0

Lo hice, y reconstruí el proyecto, pero tampoco funciona. –

+0

Acabo de encontrar http: // stackoverflow.com/questions/3341754/así que creo que no es tan fácil como pensé – mjn

+0

Lo pensé, pero no creo que sea una solución factible, tengo alrededor de 13 letras para comparar, usar valores numéricos será más difícil de depurar , pero lo usaré si no tengo otra solución: - /. –

3

Esto sucede porque set of char tipo estructurado (limitado a 256 elementos máximo) no es compatible con Unicode en absoluto. Es decir, cualquier carácter Ord(ch) > High(AnsiChar) se trunca en el constructor del conjunto y se emite una advertencia W1061 sobre el estrechamiento de WideChar a AnsiChar. Mire el siguiente caso de prueba:

{ naturally, fails, emits CharInSet() suggestion } 
    Result := 'س' in ['S','س']; 

    { fails because second argument is set of AnsiChar } 
    Result := CharInSet(
    'س', 
    ['S','س'] 
); 

    { workaround for WideChar in AnsiCharSet, fails } 
    Result := WideStrUtils.InOpSet(
    'س', 
    ['S','س'] 
); 

    { a syntactical workaround, which finally works } 
    Result := WideStrUtils.InOpArray(
    'س', 
    ['S','س'] 
); 

    if Result then 
    ShowMessage('PASS') 
    else 
    ShowMessage('FAIL'); 
2

Además.

Los conjuntos están limitados a valores ordinales de 256 elementos. Entonces AnsiChar se ajusta y (Unicode) Char no encaja. Puede usar CharInSet para portar versiones pre-unicode de Delphi a las versiones unicode. Debido a la limitación establecida, los conjuntos ya no son muy útiles con Chars.

La razón de esto es que los conjuntos se implementan como máscaras de bits. Usted es libre de implementar su propia versión de un conjunto. Por ejemplo:

type 
    TSet<T> = class 
    public 
    procedure Add(const AElem: T); 
    function InSet(const AElem: T): Boolean; 
    end; 
0

Uso TCharHelper.IsInArray de la siguiente manera:

if Edit1.Text[1].IsInArray(['S','س']) then 
    ShowMessage('Found') 
else 
    ShowMessage('Not Found'); 
Cuestiones relacionadas