Przełączniki w programie uruchamianym z linii poleceń, problem z zapisaniem warunków ich obsługi.

0

Cześć,
Zaczynam się dopiero uczyć programowania. W pierwszym programie na studiach muszę dodać obsługę przełączników, aby po uruchomieniu z linii poleceń program się wykonał i zamknął.
Potrzebuję 4 przełączniki.. -i po nim nazwa pliku wejsciowego, oraz -o po nim nazwa pliku wyjsciowego.
param1 i param 2 to zmienne - w ktorych sa przechowywane nazwy plikow.
Warunki jakie stworzyłem są postaci:

param1:=paramstr(2);
param2:=paramstr(4);  
if paramstr(1)='-o' then
  begin
   param1:=paramstr(4);
   param2:=paramstr(2);
   if paramstr(3)<>'-i' then help;
  end
 else
  if paramstr(1)<>'-i' then help
  else
    if paramstr(3)<>'-o' then help;

Problem w tym, że nie jest to najlepszy sposób ich zapisu. Na zajęciach prowadzący podpowiedział mi, żebym zapisał to w postaci pętli (chyba while jeśli dobrze pamiętam).
Siedzę tak nad tym już kolejny dzień z rzędu i nic nie umiem wymysleć.
Z góry dzięki za odpowiedzi.

0

Za pomocą pętli najlepiej for przeszukuj każdy parametr i sprawdzaj jego nazwę; w ParamCount masz ilość parametrów.

0

Ja nadal zachodzę w głowę, z czym to ludzie mają problemy. Ja rozmumiem początki. Ale w takim razie dlaczego autor wątku nie zaczął od poszukania rozwiązania w Google. Poza tym skoro początki, to dlaczego - do stu tysięcy nietagujących wątki uparciuchów (chociaż ten chyba wyjątkowo ma tag, to jakiś plus) ten wątek nie jest w dziale Newbie. Muszę przenosić. I wiem, że gotowcami się Was leniuchy w większości krzywdzi krzywdzi, ale to przedostatni raz zapodaję, obiecuję. Bo się zastanawiam jakież to ludzie mają problemy skoro zadaje się im tak łatwe zadania żeby pewnie tylko zaliczyli. I chyba też celowo, aby się zbytnio nie męczyli wymyślając rozwiązanie. Ale pewnie niektórych męczy te samodzielne myślenie. A i znowu w pytaniu mamy do czynienia = z tak zwanym formatowaniem "z d**y", nie wspominając o tym, że kod źródłowy Delphi wstawiamy w opowiedni znacznik. Ok, ponarzekałem sobie, niczym @-321oho, ale i tak zarówno ja, jak i On nic tym nie zmieniemy niestety. A ponieważ zbliża się za pewne wielkimi krokami, o ile już się nie zaczął "sezon zaliczeń" na wszelkiej maści szczebla uczelniach (około) informatycznych. To zaleją nas niestety tutaj podobne do tego wątki. Ech... :/ Ok, ay wynagrodzić dotarcie do końca mojego wywodu, oto idiotoodporny kod gotowiec, który przetestowałem. Jest też on w stylu WinAPI, bez użycia modułów VCL.

program i_z_czym_tutaj_mozna_miec_problem;

{$APPTYPE CONSOLE}

uses
  Windows;

const
  Param1 = '-i';
  Param2 = '-o';

function OEMWrite(AnsiText : string) : string;
begin
  Result := '';
  if AnsiText <> '' then
  begin
    SetLength(Result, Length(AnsiText));
    AnsiToOEM(PChar(AnsiTexT), PChar(Result));
  end;
end;

function AnsiLowerCase(const S : string) : string;
var
  Len : integer;
begin
  Len := Length(S);
  SetString(Result, PChar(S), Len);
  if Len > 0 then
  begin
    CharLowerBuff(Pointer(Result), Len);
  end;
end;

function ExtractFileName(FileName : string) : string;
var
  I : integer;
begin
  ExtractFileName := FileName;
  for I := Length(FileName) downto 1 do
  begin
    if (FileName[I] = '\') then
    begin
      ExtractFileName := Copy(FileName, I + 1, MaxInt);
      Break;
    end;
  end;
end;

function FileExists(const FileName : string) : boolean;
const
  FILE_ATTRIBUTE_REPARSE_POINT = 1024;
var
  FileHandle : THandle;
  WFD : TWin32FindData;
begin
  Result := False;
  FileHandle := Windows.FindFirstFile(PChar(FileName), WFD);
  if FileHandle <> INVALID_HANDLE_VALUE then
  begin
    Result := (WFD.dwFileAttributes and FILE_ATTRIBUTE_REPARSE_POINT = 0)
      and (WFD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0);
    Windows.FindClose(FileHandle);
  end;
end;

procedure ShowParamsHelp;
begin
  Writeln(OEMWrite('Nieprawidłowe parametry!'));
  Writeln(OEMWrite('Użycie programu: ' + ExtractFileName(ParamStr(0)) +
    ' -i <plik_wejściowy> -o <plik_wyjściowy>'));
  Halt(1);
end;

procedure ShowFileNotExistsError(FileNameParam : string; IsInputFile : boolean);
const
  ErrorCodeArr : array[boolean] of Byte = (3, 2);
  FileKindText : array[boolean] of string = ('wyjściowy', 'wejściowy');
begin
  Writeln(OEMWrite('Plik ' + FileKindText[IsInputFile] + ': ' + FileNameParam + ' nie istnieje!'));
  Halt(ErrorCodeArr[IsInputFile]);
end;

var
  I : integer;
  Param1Set, Param2Set : boolean;
  S, FileInName, FileOutName : string;
begin
  Param1Set := False;
  Param2Set := False;
  for I := 1 to ParamCount do
  begin
    S := AnsiLowerCase(ParamStr(I));
    if (ParamStr(I) = Param1) or (ParamStr(I) = Param2) then
    begin
      if I + 1 <= ParamCount then
      begin
        S := ParamStr(I + 1);
        if not Param1Set then
        begin
          Param1Set := True;
        end
        else
        begin
          Param2Set := True;
        end;
        if FileExists(S) then
        begin
          if not Param2Set then
          begin
            FileInName := S;
          end
          else
          begin
            FileOutName := S;
          end;
        end
        else
        begin
          ShowFileNotExistsError(S, not Param2Set);
        end;
      end;
    end;
  end;
  if (not Param1Set) or (not Param2Set) then
  begin
    ShowParamsHelp;
  end
  else
  begin
    Writeln(OEMWrite('Plik wejściowy: ' + FileInName));
    Writeln(OEMWrite('Plik wyjściowy: ' + FileOutName));
  end;
  Writeln(OEMWrite('NACIŚNIJ ENTER'));
  Readln;
end.

EDIT: a i tak wiem, pewnie gdzieś jest literówka albo jakiś inny błąd, wiem że pewnie da się to też zrobić inaczej. Ale ja widząc jak się niektórzy męczą to sam siadam do kompilatora i kombinuje po chwili mając rozwiązanie i dalej żyjąć w niewiedzy: z czym problem? A no tak z zapisaniem warunków ich obsługi, toż to wystarczyło znać petle for i instrukcje if, które to są banałami by ów "problem" rozwiązać.

0

Zdazylem to poznac, najwidoczniej za malo cwiczylem.
Dziękuję za poświęcenie mi czasu. Właśnie podczas przeglądania stron w google natrafiłem na to forum i postanowiłem poszukać pomocy tutaj, bo nigdzie "podobnego" problemu nie widziałem.
Za parę lat jak dowiem się co to programowanie z czym to się je, zapewne będzie to dla mnie tak samo łatwe, na razie jednak nie jest.
Mając ten kod na pewno coś wymyślę odnośnie swojego programu. Jeszcze raz dzięki.

0
olesio napisał(a)

Bo ostatni raz to też może był przeodstatni raz. Poza tym na pewno nie widziałeś tej obietnicy aż setki razy, a nawet pewnie i nie dziesiątki razy. Gorszy ode mnie z penoscią jest niejaki donald t. ponieważ obiecywał coś częściej niż ja i niedotrzymanie tego co obiecał jest bardziej szkodliwe dla ludzi niż moje sporadyczne od długiego czasu gotowce. Ale to nie temat na te forum. Anyway, ja też się czegoś przy okazji nauczyłem, że należy pamiętać o Dispose. Oraz, że można inaczej użyć funkcji AnsiToOEM, na przykład bez potrzeby pamiętania o Dispose itp :)

@olesio czy możesz zaznaczać modyfikacje jakie wprowadzasz w post? Bo już miałem zamiar nazwać @_13h_Dragon wyciekiem pamięci gdyż myślałem że odnosi się on do aktualnego kodu.
Tak generalnie to nie pamiętam kiedy ostatnio użyłem GetMem poza lowlevel stuff, tablice dynamiczne są zazwyczaj dużo lepszymi kontenerami pamięci.

Mając ten kod na pewno coś wymyślę odnośnie swojego programu. Jeszcze raz dzięki.

Bądź grzeczny i optaszkuj rozwiązanie (byle nie swoim ptaszkiem).

1 użytkowników online, w tym zalogowanych: 0, gości: 1