2014-09-16 3 views
6

StrUtils.SearchBuf[soWholeWord,soDown] 옵션으로 테스트 할 때 예기치 않은 결과가 발생했습니다.SearchBuf 예기치 않은 출력

program Project1; 

Uses 
    SysUtils,StrUtils; 

function WordFound(aString,searchString: String): Boolean; 
begin 
    Result := SearchBuf(PChar(aString),Length(aString), 0, 0, searchString, 
    [soWholeWord,soDown]) <> nil; 
end; 

Procedure Test(aString,searchString: String); 
begin 
    WriteLn('"',searchString,'" in "',aString,'"',#9,' : ', 
    WordFound(aString,searchString)); 
end; 

begin 
    Test('Delphi','Delphi'); // True 
    Test('Delphi ','Delphi'); // True 
    Test(' Delphi','Delphi'); // False 
    Test(' Delphi ','Delphi'); // False 
    ReadLn; 
end. 

' Delphi'하고 ' Delphi '은 전체 단어로 간주되지?

역방향 검색은 어떻게됩니까?

function WordFoundRev(aString,searchString: String): Boolean; 
begin 
    Result := SearchBuf(PChar(aString),Length(aString),Length(aString)-1,0,searchString, 
    [soWholeWord]) <> nil; 
end; 

Procedure TestRev(aString,searchString: String); 
begin 
    WriteLn('"',searchString,'" in "',aString,'"',#9,' : ', 
    WordFoundRev(aString,searchString)); 
end; 

begin 
    TestRev('Delphi','Delphi'); // False 
    TestRev('Delphi ','Delphi'); // True 
    TestRev(' Delphi','Delphi'); // False 
    TestRev(' Delphi ','Delphi'); // True 
    ReadLn; 
end. 

나는이 사실을 전혀 알지 못합니다. 함수가 버그가 있음을 제외하고.

XE7, XE6 및 XE에서 같은 결과가 나타납니다.


업데이트

QC127635 StrUtils.SearchBuf fails with [soWholeWord] option

+1

품질 관리 예에서 언급 된 다른 버그가 있습니다 [리포트 : 122357] (http://qc.embarcadero.com/wc/qcmain.aspx?d = 122357) – bummi

+1

@bummi, 네 QC를 검색 한 결과이 현상이 발생하지 않았습니다. –

답변

4

그것은 나에게 벌레처럼 보인다. 다음은 검색을 수행하는 코드는 다음과 같습니다

while SearchCount > 0 do 
begin 
    if (soWholeWord in Options) and (Result <> @Buf[SelStart]) then 
    if not FindNextWordStart(Result) then Break; 
    I := 0; 
    while (CharMap[(Result[I])] = (SearchString[I+1])) do 
    begin 
    Inc(I); 
    if I >= Length(SearchString) then 
    begin 
     if (not (soWholeWord in Options)) or 
     (SearchCount = 0) or 
     ((Byte(Result[I])) in WordDelimiters) then 
     Exit; 
     Break; 
    end; 
    end; 
    Inc(Result, Direction); 
    Dec(SearchCount); 
end; 

while 루프 라운드마다 우리는 soWholeWord이 옵션에 있는지 확인하고 다음 단어의 시작 부분으로 진행합니다. 그러나 우리는

Result <> @Buf[SelStart] 

지금, Result 버퍼에 현재 포인터, 일치를위한 후보자으로 전진하면 그렇게. 따라서이 테스트는 검색중인 문자열의 시작 여부를 확인합니다.

이 테스트가 의미하는 바는 검색된 문자열이 영숫자가 아닌 텍스트로 시작하는 경우 영숫자가 아닌 텍스트를 첫 단어의 시작 부분까지 넘길 수 없다는 것입니다.

지금, 당신은

Result <> @Buf[SelStart] 

에 대한 테스트를 제거하는 결정할 수 있습니다 그러나 당신이 경우에 당신이 바로 문자열의 시작에있는 경우 더 이상 단어를 일치하지 찾을거야. 그래서 당신은 다른 방식으로 실패 할 것입니다. 이 문제를 해결할 올바른 방법은 우리가 문자열의 시작 부분에있는 경우 FindNextWordStart이 진행되지 않고 문자가 영숫자로되어 있는지 확인하는 것입니다. 그들이 문자열의 시작 단어가 일치하지 않을 것을 발견

다음
if (soWholeWord in Options) then 
    if not FindNextWordStart(Result) then Break; 

과에 코드를 변경 :

if (soWholeWord in Options) and (Result <> @Buf[SelStart]) then 
    if not FindNextWordStart(Result) then Break; 

내 생각 엔 원래 저자는이 같은 코드를 작성한다는 것입니다

그리고 아무도 영숫자가 아닌 텍스트로 시작된 문자열을 테스트했습니다.

는 이 같은

뭔가 작업을 끝낼 것 :

if (soWholeWord in Options) then 
    if (Result <> @Buf[SelStart]) or not Result^.IsLetterOrDigit then 
    if not FindNextWordStart(Result) then Break; 
+2

'그리고 문자열이 영숫자가 아닌 텍스트로 시작하면 어떤 일이 일어 났는지 아무도 테스트하지 못했습니다. 한숨과 너무 오랜 세월 그리고 아무도 전에 이것을 발견하지 못했습니다. 이 테스트는 사소한 일이며 RTL이 Emba에 의해 단위 테스트를 받았는지 궁금합니다. 감사합니다. 나중에 QC를 보내 드리겠습니다. –

+2

흠. 나 시작하지 마라 !! –

+0

@DavidHeffernan 원래 코드를 제안 코드로 바꾸었지만 여전히 작동하지 않습니다. 문제의 예제는 동일한 결과를 반환합니다. 델파이 10.1 또는 10.2. –