Losowanie plików

0

Witam. Potrzebuję funkcję napisaną w Delphi, która będzie losować jakiś plik (spośród kilkunastu), a następnie wyświetlać jego zawartość. Ogólnie ma to być program - test (spośród 50 pytan losuje 25 i na końcu podaje ilość poprawnych odpowiedzi). Pytania chciałbym zapisać w plikach.

0
  1. Wyszukać wszystkie pliki z pytaniami (FindFirst - FindNext - FindClose), ich nazwy zapamiętać w tablicy np. tab:array of string.
  2. Wylosować index:=Random(Length(tab)), ew. sprawdzić czy index nie powtórzył się.
  3. Wyświetlić zawartość pliku tab[index].
0

ponazywać pliki wg wzoru "plik_i_.xxx" gdzie i to iteracja, po kolei 1, 2, 3, 4... itd. A potem w delphi zrobić losowanie integera i otworzyć plik z odpowiednim indexem. Czego z tego nie rozumiesz?

0

może lepiej pytania zapisywać w jednym pliku, o określonym formacie? np.

Jakiego koloru jest biały maluch?|zielony|biały|niebieski|2
Gdzie się odbywa festiwal w Cannes?|w Cannes|w Wałbrzychu|w Benghazi|1

gdzie cyfra na końcu oznacza która odpowiedź jest prawidłowa

0

Dopiero zaczynam nauke Delphi, takze prosze o wyrozumiałość. Mam jeszcze jedno pytanie. Mam instrukcje

 
procedure TForm1.FormCreate(Sender: TObject);

begin

if FileExists('pytania\*.txt') then
------------- w tym miejscu chciałbym, żeby program przechodził do innej procedury jak to napisać?  
else
ShowMessage('Brak pytań!');
Halt;
end;
0
 
procedure InnaProcedura;
begin
//zawartość procedry
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  if FileExists('pytania\*.txt') then
    InnaProcedura  
  else
  begin
    ShowMessage('Brak pytań!');
    Halt;
  end;
end;
0

A dałoby się zrobić coś takiego? - Sprawdź czy w pliku znajduje sie jakas liczba x ? Jeśli tak to w jaki sposob?

0

Najprościej to chyba tak - użyć takiej funkcji:

function IsDigitIFile(WhatFile : string; WhatDigit : integer) : boolean;
var
  SL : TStringList;
begin
  Result := False;
  if FileExists(WhatFile) then
  begin
    SL := TStringList.Create;
    SL.LoadFromFile(WhatFile);
    Result := Pos(IntToStr(WhatDigit), SL.Text) > 0;
    SL.Free;
  end;
end;

I wywołać ją sprawdzając choćby tak:

const
  AWhatDigit = 3;
  AWhatFile = 'D:\plik.txt';
begin
  if IsDigitIFile(AWhatFile, AWhatDigit) then
  begin
    ShowMessage('Liczba ' + IntToStr(AWhatDigit) + ' jest w pliku ' + AWhatFile);
  end
  else
  begin
    ShowMessage('Liczba ' + IntToStr(AWhatDigit) + ' NIE występuje w pliku ' + AWhatFile);
  end;
end;

Jednak polecał bym Tobie najpierw poznać podstawy czytając kompendium na stronie 4p lub różne kursy dla początkujących do znalezienie w google, bo tak to będziesz co chwila pytał o jakiś banał, a nic się nie nauczysz, a takie programowanie w stylu umieszcze kilka komponentów na formatce, a o to jak zrobić to i owo zapytam na forum i program jakoś sam się zrobi - kompletnie nie ma sensu. Dodam jeszcze tylko, że funkcja FileExists musi mieć podaną ewentualną ścieżkę i obowiązkowo pełną nazwę pliku inaczej pokaże Tobie wyjątek. Natomiast wyszukiwanie plików najprościej zrobić funkcjami z WinAPI w taki sposób jak poniżej. Dodam, że u mnie katalog 'D:\a' istnieje i są w nim pliki exe. Jeśli natomiast chcesz zrobić wyszukiwanie rekursywne aby odnaleźć podkatalogi i w nich kolejne pliki to pogoogluj sobie za jakimiś przykładami lub pokombinuj samodzielnie. Przynajmniej się czegoś nauczysz, poza ułożeniem kontrolek na formatce, co oczywiście programowaniem z pewnością nazwać nie można.

const
  FindWhat = 'D:\a\*.exe';
var
  H : THandle;
  WFD : TWIN32FindData;
begin
  Memo1.Lines.Clear;
  H := Windows.FindFirstFile(PChar(FindWhat), WFD);
  if H <> INVALID_HANDLE_VALUE then
  begin
    repeat
      Memo1.Lines.Add(ExtractFilePath(FindWhat) + WFD.cFileName);
    until not Windows.FindNextFile(H, WFD);
    Windows.FindClose(H);
  end;
end;
0

Zamierzam tak się uczyć zaawansowanych rzeczy, ale myślę, że dobrze uczyc sie na przykładach. Moge prosic jeszcze o wytłumaczenie pierwszej czesci kodu?

1

Czego nie rozumiesz. Pogoogluj i poczytaj jak działa TStringList, to obiekt przechowujący stringi, a funkcja Pos opisana jest tutaj: Pos i źle podchodzisz do nauki, w kompendium na stronei 4p są oprócz wytłumaczenia podstaw także podawane przykłady. Przyswajając wiedzę z kompendium nauczysz się samodzielnie pisać takie programy, jakie będą Tobie potrzebne. To tak nie działa, że ułóżysz sobie komponenty, a później masz 100 pytan do. Ponieważ wszystkie początkowe wątpliwości rozwieje Tobie przyswojenie wiedzy o absolutnych podstawach, o które pytasz.

0

Potrzebuje jeszcze jedną rzecz. Chcę zapisywać liczby w pliku ale tak, by przy każdym kolejnym zapisie liczba była o 1 linię niżej. Chodzi o to by nie nadpisywać poprzedniej liczby

0

Append

0
const
  AWhatDigit = 3;
  AWhatFile = 'D:\plik.txt';
begin
  if IsDigitIFile(AWhatFile, AWhatDigit) then
  begin
    ShowMessage('Liczba ' + IntToStr(AWhatDigit) + ' jest w pliku ' + AWhatFile);
  end
  else
  begin
    ShowMessage('Liczba ' + IntToStr(AWhatDigit) + ' NIE występuje w pliku ' + AWhatFile);
  end;
end; 

Co do tego kodu, wywala mi bład ze niezadeklarowano IsdigitFile gdzie mam to zadeklarowac?

0

Ech...
Najpierw się uczy podstaw!

0

-.- napisałem wczesniej ze dopiero sie ucze... wiec powie mi ktos co mam z tym zrobic?

0
olesio napisał(a)

Najprościej to chyba tak - użyć takiej funkcji:

function IsDigitIFile(WhatFile : string; WhatDigit : integer) : boolean;
var
  SL : TStringList;
begin
  Result := False;
  if FileExists(WhatFile) then
  begin
    SL := TStringList.Create;
    SL.LoadFromFile(WhatFile);
    Result := Pos(IntToStr(WhatDigit), SL.Text) > 0;
    SL.Free;
  end;
end;

Nie jest to dobre rozwiązanie.
Jeżeli w pliku mamy np liczby 258 34 to IsDigitIFile('nazwa_pliku',5) zwróci True.
No chyba, że interesuje Cię wyszukiwanie cyfr...

0

maja tam byc takze liczby w zakresie 1-60. Jakie inne rozwiazanie proponujesz?

0

Jako rozwiązanie Twoich problemów polecam szczerze raz jeszcze: PRZECZYTAJ KOMPENDIUM LUB RÓŻNE KURSY Z PODSTAWAMI DO ZNALEZIENIA W GOOGLE!!! Sorry za krzyk, ale jak piszę nie krzycząc to chyba do Ciebie nie dociera. A teraz na szybko wykombinowałem poniższą funkcję. Powinna działać. Jak nadal coś nie tak to sobie ją dostosuj już sam. Funkcja działa przy założeniu, że znakiem nowej linii jest CRLF. Natomiast co do pytania jak dodać jakąs liczbę do pliku, to ja bym przy pisaniu pod VCL posłużył się TStringList. Załądował do tego obiektu plik i robiąc TwojaStringLista.Add('Tekst'); dodasz na pewno do pliku nową linijkę. To czy dana linijka istnieje już w pliku sprawdzisz funkcją IndexOf, która jeżeli zwróci -1 oznacza, że takiej linijki na niej nie ma. Funkcja ignoruje wielkość liter, także do sprawdzania czy w poprzednich linijkach nie ma jakiejś liczby przekonwerowanej na string nada się w zupełności.

function IsDigitInFile(WhatFile : string; WhatDigit : integer) : boolean;
var
  S : string;
  X, L : integer;
  SL : TStringList;
begin
  Result := False;
  if FileExists(WhatFile) then
  begin
    SL := TStringList.Create;
    SL.LoadFromFile(WhatFile);
    S := SL.Text;
    SL.Free;
    X := Pos(IntToStr(WhatDigit), S);
    L := Length(IntToStr(WhatDigit));
    while X > 0 do
    begin
      Result := ((S[X - 1] = '') or (S[X - 1] = ' ') or (S[X - 2] = #13) or (S[X - 1] = #10))
        and ((S[X + L] = '') or (S[X + L] = ' ') or (S[X + L] = #13) or (S[X + L + 1] = #10)
        or not (S[X + L] in ['0'..'9']));
      if Result then
      begin
        Break;
      end
      else
      begin
        Delete(S, 1, X + L);
      end;
      X := Pos(IntToStr(WhatDigit), S);
    end;
  end;
end;

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