Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Parsen von Seitenzahlen (https://www.delphipraxis.net/137353-parsen-von-seitenzahlen.html)

himitsu 17. Aug 2012 15:48

AW: Parsen von Seitenzahlen
 
Zitat:

Delphi-Quellcode:
function CreateNumberList(aNumberDesc: string; var aNumberList: TList<Integer>): Boolean;

Weg mit dem VAR, denn du willst ja nur den Objektinhalt ändern und nicht den Instanzzeiger.

Popov 17. Aug 2012 16:29

AW: Parsen von Seitenzahlen
 
Ich hab so Just4Fun das Problem im ersten Post gelöst. Es funktioniert relativ gut, zumindest bei der Aufgabenstellung

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
    function IntList(s: String; List: TStrings): Boolean;
        function IsValidInteger(S: String): Boolean;
        var
          I, Code: Integer;
        begin
          Val(S, I, Code);
          Result := Code = 0;
        end;
    var
      a, b: String;
      i: Integer;
    begin
      Result := False;
      List.Clear;

      if Pos('-', s) = 0 then //für einzelne Seitenzahlen, z. B. "1"
      begin
        if IsValidInteger(s) then
        begin
          List.Add(Trim(s));
          Result := True;
        end;
        Exit;
      end;

      a := Copy(s, 1, Pos('-', s) - 1); //für Seitenzahlen von bis, z. B. "1-3"
      Delete(s, 1, Pos('-', s));
      b := s;

      if IsValidInteger(a) and IsValidInteger(b) then
      begin
        for i := StrToInt(a) to StrToInt(b) do
          List.Add(IntToStr(i));
        Result := True;
      end;
    end;
var
  s: String;
  sl, slList, slResult: TStringList;
  i: Integer;
begin
  s := '1-3; 10; 17; 21-23';

  sl := TStringList.Create;
  slList := TStringList.Create;
  slResult := TStringList.Create;
  try
    sl.Delimiter := ';';
    sl.DelimitedText := s;
    for i := 0 to sl.Count - 1 do
      if IntList(sl[i], slList) then
        slResult.AddStrings(slList);

    ListBox1.Items.Text := slResult.Text;
  finally
    sl.Free;
    slList.Free;
    slResult.Free;
  end;
end;

Furtbichler 17. Aug 2012 18:45

AW: Parsen von Seitenzahlen
 
Das wäre dann die dritte funktionierende Lösung.

Popov 17. Aug 2012 19:04

AW: Parsen von Seitenzahlen
 
Wie gesagt, nicht wirklich eine Lösung (Problem von 2009), aber etwas Just4Fun Programmierung.

Furtbichler 18. Aug 2012 08:32

AW: Parsen von Seitenzahlen
 
IsValidNumber durch 'TryStrToInt' ersetzen und dann noch das dreimalige Ermitteln der Position von '-' durch Refaktorisieren entfernen. Dann wird das auch kompakter. Das Ziel sollte ein Boolean-Array oder ein Integer-Array sein, keine ListBox.

Deine Lösung unterscheidet sich eigentlich nicht von den anderen, außer, das Du sie nicht allgemeingültig gemacht (Ausgabe in eine ListBox) und als Buttonclick implementiert hast. Einzig das separieren der durch Semikolon getrennten Einzelbereiche bewerkstelligst Du über eine Stringliste.

Aber falsch ist es nicht, nur die Fehlerbehandlung ist ungenügend, finde ich.

@Jens01: TrimString ist überflüssig. Das trimmen übernimmt die ExtractString-Funktion

Sir Rufo 18. Aug 2012 10:44

AW: Parsen von Seitenzahlen
 
Wäre es nicht wesentlich schicker dieses mit dem State-Pattern zu lösen?

State-Pattern: CSV-Parser

Bjoerk 18. Aug 2012 12:14

AW: Parsen von Seitenzahlen
 
Hab' auch noch einen (mit Syntaxprüfung, allerdings ungetestet) und auch noch eine Frage dazu. Ist es möglich herauszufinden, ob (wie in meinem Fall) der AdobeRader diese Seiten tatsächlich gedruckt hat (Logdatei o.ä.) ?

Delphi-Quellcode:
function TrimAll(const S: string): string;
var
  I: integer;
begin
  Result := S;
  for I := Length(Result) downto 1 do
    if Result[I] = ' ' then
      Delete(Result, I, 1);
end;

function IsInPrintOrder(const AValue: integer; const ASet: string): boolean;
type
  TStatus = (stWaitForInteger1, stWaitForInteger2, stError,
    stReadyForInteger1, stReadyForInteger2);
var
  Status: TStatus;
  T, T1, T2: string;
  I, I1, I2: integer;
begin
  T1 := '';
  T2 := '';
  Result := false;
  T := TrimAll(ASet) + ';';
  Status := stWaitForInteger1;
  for I := 1 to Length(T) do
    if (Status <> stError) then
    begin
      case Status of
        stWaitForInteger1:
          if T[I] in ['0'..'9'] then
            T1 := T1 + T[I]
          else
            if T[I] = '-' then
              Status := stWaitForInteger2
            else
              if T[I] in [',', ';'] then
                Status := stReadyForInteger1
              else
                Status := stError;
        stWaitForInteger2:
          if T[I] in ['0'..'9'] then
            T2 := T2 + T[I]
          else
            if T[I] in [',', ';'] then
              Status := stReadyForInteger2
            else
              Status := stError;
      end;
      case Status of
        stReadyForInteger1:
          if TryStrToInt(T1, I1) then
          begin
            Status := stWaitForInteger1;
            if AValue = I1 then
            begin
              Result := true;
              Break;
            end
            else
              T1 := '';
          end
          else
            Status := stError;
        stReadyForInteger2:
          if TryStrToInt(T1, I1) and TryStrToInt(T2, I2) and (I2 >= I1) then
          begin
            Status := stWaitForInteger1;
            if (AValue >= I1) and (AValue <= I2) then
            begin
              Result := true;
              Break;
            end
            else
            begin
              T1 := '';
              T2 := '';
            end;
          end
          else
            Status := stError;
      end;
    end;
  if Status = stError then
    raise Exception.Create('Invalid Syntax');
end;

end.

Jens01 18. Aug 2012 12:32

AW: Parsen von Seitenzahlen
 
Zitat:

@Jens01: TrimString ist überflüssig. Das trimmen übernimmt die ExtractString-Funktion
Dies Trimmen ist doch etwas anderes als was ExtractString macht. Ich nehme dort alle überflüssigen Leerzeichen raus und kann die restlichen dann durch ein ';' ersetzen. So hat der Anwender die Möglichkeit, Leerzeichen, Komma und Semikolon als Trennzeichen zu nutzten.

Furtbichler 18. Aug 2012 13:04

AW: Parsen von Seitenzahlen
 
Oh, dann habe ich nicht richtig hingeschaut, was die Funktion macht.

Furtbichler 18. Aug 2012 13:06

AW: Parsen von Seitenzahlen
 
Zitat:

Zitat von Sir Rufo (Beitrag 1178681)
Wäre es nicht wesentlich schicker dieses mit dem State-Pattern zu lösen?

Schicker vielleicht, aber nicht unbedingt lesbarer und ein klein wenig Overkill.
Ich hätte noch RegEx anzubieten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:14 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz