2010-11-21 41 views
16

Tôi đã cập nhật một ứng dụng từ Delphi 2007 đến Delphi 2010, tất cả mọi thứ diễn ra tốt đẹp, ngoại trừ một tuyên bố rằng biên soạn tốt nhưng không được làm việc đó là:CharInSet không hoạt động với các chữ cái không phải tiếng Anh?

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

Tuy nhiên, tôi biết rằng trong sẽ không, vì vậy tôi đã thay đổi để CharInSet

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

nhưng nó không bao giờ làm việc khi chuỗi là س, nhưng luôn luôn làm việc với S, thậm chí tôi cast edt1.Text 1 với AnsiChar nó luôn luôn không hoạt động chữ tiếng Ả rập.

Làm bất cứ điều gì sai, hoặc nó không phải là cách CharInSet hoạt động ?, hoặc đó là một lỗi trong CharinSet?

UPDATE:

lớn Bạn tôi Issam Ali đã gợi ý một giải pháp mà đã làm việc tốt vì nó:

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

loại gì là 'edt1'? – dan04

+0

@ dan04, đó là TEdit, tôi đã thay đổi mã để hiển thị nó là chỉnh sửa thay vì edt –

+3

Trình biên dịch phát ra cảnh báo sau bằng mã CharInSet của bạn: [Cảnh báo DCC] Unit5.pas (30): W1061 Thu hẹp cho hằng số WideChar (# $ 0633) để AnsiChar mất thông tin –

Trả lời

17

CharInSet là vô ích cho các nhân vật trên 255. Trong trường hợp của bạn, bạn nên sử dụng

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

Làm việc tốt cảm ơn bạn, tôi đã không nghĩ đến, bởi vì tôi nghĩ rằng nó sẽ có cùng một vấn đề như trong. –

1

Bạn đã thiết lập mã hóa của file nguồn của bạn để UTF-8 (click chuột phải để mở trình đơn ngữ cảnh)? (Mặc định là ANSI iirc, trong đó sẽ không hoạt động.)

+0

Tôi đã làm và xây dựng lại dự án, nhưng cũng không hoạt động. –

+0

Chỉ tìm thấy http: // stackoverflow.com/questions/3341754/vì vậy tôi nghĩ rằng nó không phải là dễ dàng như tôi nghĩ – mjn

+0

Tôi nghĩ về nó, nhưng tôi did't cảm thấy đó là một giải pháp khả thi, tôi có khoảng 13 chữ cái để so sánh, sử dụng giá trị số sẽ khó khăn hơn trong gỡ lỗi , nhưng tôi sẽ sử dụng nó nếu tôi không có giải pháp khác: - /. –

3

Điều này xảy ra bởi vì set of char cấu trúc loại (giới hạn 256 yếu tố tối đa) không hỗ trợ Unicode. Nghĩa là, bất kỳ ký tự nào Ord(ch) > High(AnsiChar) bị cắt ngắn trong hàm tạo và cảnh báo W1061 về việc thu hẹp WideChar thành AnsiChar đang được phát ra. Xem thử nghiệm sau:

{ 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

Ngoài ra.

bộ được giới hạn ở các giá trị thứ tự của 256 phần tử. Vì vậy, AnsiChar phù hợp và (Unicode) Char không phù hợp. Bạn có thể sử dụng CharInSet để chuyển các phiên bản trước unicode của Delphi thành các phiên bản unicode. Do giới hạn đã đặt, các bộ không phải là vô cùng hữu ích nữa với Chars.

Lý do đằng sau điều này, là các bộ được triển khai dưới dạng bitmap. Bạn được tự do triển khai phiên bản của riêng bạn. Ví dụ:

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

Sử dụng TCharHelper.IsInArray như sau:

if Edit1.Text[1].IsInArray(['S','س']) then 
    ShowMessage('Found') 
else 
    ShowMessage('Not Found'); 
Các vấn đề liên quan