2014-02-18 2 views
3

문자열이 "니모닉 유형"인지 확인하려고합니다 ... 내 니모닉 유형은 'a'에서 'z'로, 'A'에서 'Z' '0'에서 '9'까지의 숫자와 '_'의 추가 숫자가 있습니다. 아래와 같이 코드를 작성합니다. 주어진 문자열이 내 니모닉 패턴과 일치하면 참이어야 함 거짓 :Delphi - 문자열을 통해 반복

TRes := True; 
for I := 0 to (AString.Length - 1) do 
begin 
    if not ((('0' <= AString[I]) and (AString[I] <= '9')) 
     or (('a' <= AString[I]) and (AString[I] <= 'z')) 
     or (('A' <= AString[I]) and (AString[I] <= 'Z')) 
     or (AString[I] = '_')) then 
     TRes := False; 
end; 

이 코드는 항상 False로 표시됩니다.

답변

9

XE5 질문에 태그를 지정하고 0부터 시작하는 색인을 사용 했으므로 문자열이 0부터 시작한다고 가정합니다. 그러나 아마 그 가정은 착각되었습니다.

읽기가 다소 어렵지만 논리는 괜찮습니다. 문제의 코드는 이미 의도 한대로 수행하고 있습니다. 적어도 if 문은 실제로 의도 한 테스트를 수행합니다.

이해하기 쉽게 코드를 다시 작성해 보겠습니다. 나는 각 문자를 표현하기 위해 우리 다르게 배치하고, 로컬 루프 변수를 사용하려고 해요 : 그런 식으로 작성하면

for C in AString do 
begin 
    if not (
     (('0' <= C) and (C <= '9')) // C is in range 0..9 
    or (('a' <= C) and (C <= 'z')) // C is in range a..z 
    or (('A' <= C) and (C <= 'Z')) // C is in range A..Z 
    or (C = '_')     // C is _ 
) then 
    TRes := False; 
end; 

난 당신이 당신이하고자하는 테스트를 수행 동의 것이라고 확신합니다. 더 간결 CharInSet를 사용 @TLama가 말한대로

function IsValidIdentifierChar(C: Char): Boolean; 
begin 
    Result := ((C >= '0') and (C <= '9')) 
      or ((C >= 'A') and (C <= 'Z')) 
      or ((C >= 'a') and (C <= 'z')) 
      or (C = '_'); 
end; 

, 당신은 IsValidIdentifierChar을 작성할 수 있습니다 :

은 내가 IsValidIdentifierChar 함수를 작성하는 것입니다,하지만 코드를 이해하기 쉽게하려면 다음

function IsValidIdentifierChar(C: Char): Boolean; 
begin 
    Result := CharInSet(C, ['0'..'9', 'a'..'z', 'A'..'Z', '_']); 
end; 

당신 이 함수 위에 루프를 만들 수 있습니다.

TRes := True; 
for C in AString do 
    if not IsValidIdentifierChar(C) do 
    begin 
    TRes := False; 
    break; 
    end; 
+3

또는 결과 : = CharInSet (C, [ '0'.. '9', 'a'.. 'z', 'A'.. 'Z', '_'); 그 추악한 조합의 연산자 :) – TLama

+0

나는 {$ ZEROBASEDSTRINGS}을 놓쳤다. 나머지 의견을 주셔서 감사합니다. –

+0

네, 방금 당신이 모바일 플랫폼에 있다고 가정했습니다. 더 조심해야 했어. for in 루프는 여기에 친구입니다! –

5

문자열 유형은 1부터 시작합니다. 동적 배열은 0부터 시작합니다. 델파이의 미래를 위해 안전합니다.

가능한 문자 값의 범위를 테스트하는 것이 CharInSet 인 경우보다 효율적으로 (그리고보다 자세하게) 수행 할 수 있습니다.

function IsMnemonic(AString: string): Boolean; 
var 
    Ch: Char; 
begin 
    for Ch in AString do 
    if not CharInSet(Ch, [ '_', '0'..'9', 'A'..'Z', 'a'..'z' ]) then 
     Exit(False); 
    Result := True; 
end; 
+1

문자열도 '$ ZEROBASEDSTRINGS ON' (http://docwiki.embarcadero.com/RADStudio/en)을 기준으로 0이 될 수 있습니다./Zero-based_strings_ (Delphi)). –

+0

이것은 XE5입니다. 내 가정은 우리가 0을 기반 문자열을 사용하고 있습니다. 아마 그게 내 순진했다. –

+0

@LU RD, for가 더 나은 해결책 인 이유. XE5 제품군의 모든 컴파일러가 0/1 기반 옵션을 지원하는 것은 아니지만 (잘못 될 수 있음) –