2011-03-06 27 views
4

私は文字列(パスカル)で動作するプログラムを持っています。最初の文字が文字でない場合、文字列を読み込んだ後、最初の文字が文字でない限り、すべての最初の文字を削除する必要があります。私はそれを何度も書こうとしましたが、常にすべての文字列を削除します。最初の文字が文字であるまで文字列から文字列を削除するには?

プログラムは「123パーセント^ & ABC」を読み出す場合、結果は「ABC」ASCIIテーブル文字で は65..90からのものであり、97..122

からこれは私がどのくらいであるべきです

variables a: set of 65..90; 
      b: set of 97..122; 
------------------- 
    bool:=false; 
    While (bool=false) do 
    begin 
    Writeln(s[1]); 
    If (Ord(s[1]) in a) or (Ord(s[1]) in b) then 
    begin 
    bool:=true; 
    end else 
    delete(s,1,1); 
    end; 

なぜ機能しないのですか? この小さな手順で私を助けることができますか?ありがとうございました。

+0

私はいくつかのPascalを行っていないので、しばらくお待ちしていますが、あなたのプログラムはうまくいくようですが、指定した文字列の出力を貼り付けることはできますか?または最終的にはエラー – krtek

+1

また、いつものように、あなたの質問が本当の注目を集めるように、delphiタグを追加します! –

+0

私はそのプログラムで間違いを見ません。私はそのスタイルが好きではありませんが、意図した通りには動作しない理由はありません。 – CodesInChaos

答えて

13

あなたは

function RemoveNonAlphaASCIIFromStart(const Str: AnsiString): AnsiString; 
const 
    ALPHA = ['A'..'Z', 'a'..'z']; 
var 
    i: Integer; 
    firstIndex: integer; 
begin 
    result := ''; 
    firstIndex := 0; 
    for i := 1 to length(Str) do 
    if Str[i] in ALPHA then 
    begin 
     firstIndex := i; 
     break; 
    end; 
    if firstIndex > 0 then 
    result := Copy(Str, firstIndex, length(Str)); 
end; 

や、手続きもmy answer to a similar questionを参照して、Unicodeのデルファイでは動作し、より洗練された方法については、

procedure RemoveNonAlphaASCIIFromStart(var Str: AnsiString); 
const 
    ALPHA = ['A'..'Z', 'a'..'z']; 
var 
    i: Integer; 
    firstIndex: integer; 
begin 
    firstIndex := 0; 
    for i := 1 to length(Str) do 
    if Str[i] in ALPHA then 
    begin 
     firstIndex := i; 
     break; 
    end; 
    if firstIndex > 0 then 
    Delete(Str, 1, firstIndex - 1) 
    else 
    Str := ''; 
end; 

ように行うことができます。 [文字列からアルファ以外の文字をすべて削除します]

あなたのアルゴリズムはなぜ機能しませんか?さて、それは動作するはずです、それは私のために動作します。しかし、それは少しよりエレガントな形式で書くことができることがわかり

const 
    ALPHA = ['A'..'Z', 'a'..'z']; 

while true do 
    if (length(s) = 0) or (s[1] in ALPHA) then 
    break 
    else 
    delete(s, 1, 1); 

一つの問題は、しかし、OPの元のコードでsが空の文字列であれば、それは失敗するということです。実際には、s[1]は存在しません。 sがすべてアルファベット以外の文字(例:'!"#¤%)である場合でも機能しません。

+0

素晴らしい作品。ありがとうございました。 –

+0

OPよりもはるかに優れたスタイルですが、元のコードに間違いはありません。 – CodesInChaos

+1

最後のコードブロックの 'if'ステートメントのブール値短絡評価(BSCE)に依存していることに注目してください。普通のパスカルがBSCEを採用しているかどうかはわかりません。 –

2

以前のソリューションは機能しますが、非常に不便です。 2つの理由のため: 1.セット内での検索には時間がかかります 2.文字列から文字を削除するときは、文字列(オブジェクト)が文字を内部的に削除して配列などを調整する必要があります。

文字列をPCharにキャストし、その文字列を "手動で"チェックしながら、理想的にはあなたはその文字列をPCharにキャストして処理します。最初の文字が見つかるまで検索を実行させてから、DeleteStringメソッドを呼び出します。

procedure Frapp; 
var 
    TheString: string; 
    pcStr: PChar; 
    StrLen, I: Integer; 
begin 
    TheString := '123%^&abc'; 
    StrLen := Length(TheString); 
    pcStr := PChar(TheString); 

    for I := 0 to StrLen - 1 do 
    begin 
    if ((pcStr^ >= #65) and (pcStr <= #90)) or ((pcStr >= #97) and (pcStr <= #122)) then 
    begin 
     Delete(TheString, 1, I); 
     Break; 
    end; 
    Inc(pcStr); 
    end; 
end; 
+1

私の2つのアルゴリズムのどちらも繰り返しの 'Delete'呼び出しに苦しんでいないことに注意してください(本当に非常に非効率的です)。とにかく、上のコードは動作しません... –

+0

私の謝罪。あなたはDeleteをあまりにも頻繁に呼び出さないでください。しかし、なぜ私のコードがうまくいかないとお考えですか? – fmotis

+0

私はそれを試した。 '^&abc'を生成し、' abc'は生成しません。更新:しかし、私はそんなに急いで(バスに乗るため)!実際、* Delphi 2009 *以降(* Unicode *)では動作しません!しかし、純粋なANSI文字列で動作しますか?謝罪いたします! –

関連する問題