Ksiazka telefoniczna w Delphi

0

Witam,

napisałem poniższy program, ale nie chce się skompilować. Poniżej kod programu książki telefonicznej oraz komunikat błędów. Proszę o pomoc :)

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);

  TOsoba = record
    imie : string[20];
    nazwisko : string[20];
    telefon : string[20];
    email : string[50];
    end;

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  baza : array[0..100] of TOsoba;
  rozmiar : integer;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var j : integer;

begin

  for j:=0 to rozmiar-1 do

    if baza[j].nazwisko = Edit1.Text then

      begin
        Label1.Caption := baza[j].imie;
        Label2.Caption := baza[j].nazwisko;
        Label3.Caption := baza[j].telefon;
        Label4.Caption := baza[j].email;

      end;
procedure TForm1.FormCreate(Sender: TObject);
var plik : TextFile;
    linia : string;
    spacja : integer;

begin
  AssignFile(plik, 'baza.dat');
  Reset(plik);
  rozmiar:=0;
  while not Eof(plik) do
    begin
      readln(plik, linia);
      spacja:=Pos(' ', linia);
      baza[rozmiar].imie := Copy(linia, 0, spacja-1);
      linia := Copy(linia, spacja+1, Length(linia)-spacja);
      spacja:=Pos(' ', linia);
      baza[rozmiar].nazwisko := Copy(linia, 0, spacja-1);
      linia := Copy(linia, spacja+1, Length(linia)-spacja);
      spacja:=Pos(' ', linia);
      baza[rozmiar].telefon := Copy(linia, 0, spacja-1);
      linia := Copy(linia, spacja+1, Length(linia)-spacja);
      baza[rozmiar].email := linia;
      inc(rozmiar);
    end;
  CloseFile(plik);
end;

end.

link do screena kodu błędu http://imageshack.us/photo/my-images/39/picture0001vk.jpg/

0
  TOsoba = record
    imie : string[20];
    nazwisko : string[20];
    telefon : string[20];
    email : string[50];
    end;

Nie można deklarować typu/rekordu w typie, a w każdym razie nie da się tak, jak myślisz.
Musisz ten fragment dać albo przed deklarację formy lub za nią.

procedure TForm1.Button1Click(Sender: TObject);
var j : integer;

begin

  for j:=0 to rozmiar-1 do

    if baza[j].nazwisko = Edit1.Text then

      begin
        Label1.Caption := baza[j].imie;
        Label2.Caption := baza[j].nazwisko;
        Label3.Caption := baza[j].telefon;
        Label4.Caption := baza[j].email;

      end;

Czy tutaj czegoś przypadkiem nie brakuje?

Poza tym numer telefonu w 20 znakowym stringu?
Integer zajmie tylko 4 bajty, a 20 znakowy string 20 bajtów.

0

W pierwszej procedurze brakuje end; i ja bym tą częsc wczytującą plik umieścił w try... finally....
Poza tym poczytaj o packed record. Skrócisz kod o połowę.

0

Nie mogę dać integer, ponieważ występuja błąd kompilacji (złe typ zmiennych widocznie w label musi byc string). Tak się zastanawiam i nie wiem czego tu brakuje. Może pomożesz? Po poprawie program wyglada nastepujaco:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
 TOsoba = record
    imie : string[20];
    nazwisko : string[20];
    telefon : string[20];
    email : string[50];
    end;
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  baza : array[0..100] of TOsoba;
  rozmiar : integer;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var j : integer;

begin

  for j:=0 to rozmiar-1 do
    try
    if baza[j].nazwisko = Edit1.Text then

     finally
        Label1.Caption := baza[j].imie;
        Label2.Caption := baza[j].nazwisko;
        Label3.Caption := baza[j].telefon;
        Label4.Caption := baza[j].email;
      end;

procedure TForm1.FormCreate(Sender: TObject);
var plik : TextFile;
    linia : string;
    spacja : integer;

begin
  AssignFile(plik, 'baza.dat');
  Reset(plik);
  rozmiar:=0;
  while not Eof(plik) do
    begin
      readln(plik, linia);
      spacja:=Pos(' ', linia);
      baza[rozmiar].imie := Copy(linia, 0, spacja-1);
      linia := Copy(linia, spacja+1, Length(linia)-spacja);
      spacja:=Pos(' ', linia);
      baza[rozmiar].nazwisko := Copy(linia, 0, spacja-1);
      linia := Copy(linia, spacja+1, Length(linia)-spacja);
      spacja:=Pos(' ', linia);
      baza[rozmiar].telefon := Copy(linia, 0, spacja-1);
      linia := Copy(linia, spacja+1, Length(linia)-spacja);
      baza[rozmiar].email := linia;
      inc(rozmiar);
    end;
  CloseFile(plik);
end;

end.

występują 2 błędy kompilacji:
[Error] Unit1.pas(61): Statement expected but 'PROCEDURE' found (niby błąd w procedure TForm1.FormCreate(Sender: TObject);)
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'

0
procedure TForm1.Button1Click(Sender: TObject);
 var j : integer;

 begin

   for j:=0 to rozmiar-1 do
     try
     if baza[j].nazwisko = Edit1.Text then

      finally
         Label1.Caption := baza[j].imie;
         Label2.Caption := baza[j].nazwisko;
         Label3.Caption := baza[j].telefon;
         Label4.Caption := baza[j].email;
       end;

Nieco inaczej:

procedure TForm1.Button1Click(Sender: TObject);
 var j : integer;

 begin

   for j:=0 to rozmiar-1 do
     if baza[j].nazwisko = Edit1.Text then
     begin
         Label1.Caption := baza[j].imie;
         Label2.Caption := baza[j].nazwisko;
         Label3.Caption := baza[j].telefon;
         Label4.Caption := baza[j].email;
     end;
end;

Blok try..finally jest tutaj niepotrzebny, ponieważ samo przypisanie raczej nie może spowodować błędu.

0

W jaki sposób mam ustawić zmiane integer na string? W taki sposób nie działa. Wczesniej w typie telefon ustawiłem na Integer tak jak proponowałeś.

type
 TOsoba = record
    imie : string[20];
    nazwisko : string[20];
    telefon : Integer;
    email : string[50];
    end;
Label3.Caption := baza[j].IntToStr(telefon); 
0

Label3.Caption := IntToStr(baza[j].telefon);

0

@manson626: przeanalizuj sobie kod dołączony do tego posta. Pisany kiedyś na szybko, nie jest idealny, ale korzysta z klas VCL, zapisuje długości znaków przez co plik nie jest aż tak długi, bo zapisując jeden znak dodatkowo zapisujemy czterobajtową informację o jego długości. A oryginalny program napisał i kiedyś tutaj umieścił Adam Boduch, a ja tylko nieco go zmodyfikowałem i dostosowałem sobie w ramach samonauczania dawno, dawno temu :) Poza tym poczytaj kompendium z podstawami, bo brakuje Tobie elementarnej wiedzy o możłiwości konwersji typów, ich definiowania i ogólnie pewnie wielu innych zagadnieniach, bez poznania których co chwile będziesz miał 100 pytan do..., a to bez sensu ;/

0

Zrobiłem tak ja mi porawdziliście. Tylko, że teraz występuje kolejny błąd kompilacji. Dotyczy linijki

IntToStr(baza[rozmiar].telefon) := Copy(linia, 0, spacja-1);

Otóż wyskakuje ponizszy błąd w poniższej procedurze. Zmieniłem tutaj Int na Str, ponieważ kompilator wykazał, że są różne typy.

[Error] Unit1.pas(79): Left side cannot be assigned to 
procedure TForm1.FormCreate(Sender: TObject);
var plik : TextFile;
    linia : string;
    spacja : integer;

begin
  AssignFile(plik, 'baza.dat');
  Reset(plik);
  rozmiar:=0;
  while not Eof(plik) do
    begin
      readln(plik, linia);
      spacja:=Pos(' ', linia);
      baza[rozmiar].imie := Copy(linia, 0, spacja-1);
      linia := Copy(linia, spacja+1, Length(linia)-spacja);
      spacja:=Pos(' ', linia);
      baza[rozmiar].nazwisko := Copy(linia, 0, spacja-1);
      linia := Copy(linia, spacja+1, Length(linia)-spacja);
      spacja:=Pos(' ', linia);
      IntToStr(baza[rozmiar].telefon) := Copy(linia, 0, spacja-1);
      linia := Copy(linia, spacja+1, Length(linia)-spacja);
      baza[rozmiar].email := linia;
      inc(rozmiar);
    end;
  CloseFile(plik);
end;

end. 
0
IntToStr(baza[rozmiar].telefon) := Copy(linia, 0, spacja-1);

Dzisiejszy najdziwniejszy kod dnia...
Ale tak na serio:
Są dwie podstawowe funkcje do takich zamian:
IntToStr do zamiany integer na string
StrToInt do zamiany string na integer
Czyli (logicznie rzecz biorąc) tak powinno być dobrze:

baza[rozmiar].telefon := StrToInt(Copy(linia, 0, spacja-1));

Dlaczego?
Ponieważ chcemy zamienić ciąg znaków na liczbę.
Przed zamianą warto byłoby także sprawdzić, czy w ciągu znaków na pewno znajdują się same liczby.
Wystąpienie czegoś poza liczbą (kropka, przecinek, litera, etc.) spowoduje błąd.
Ewentualnie można użyć TryStrToInt; wtedy kod wyglądałby tak:

Function ZamienNaLiczbe(Str: String): Integer;
Begin
 Result := 0;
 if not TryStrToInt(Str, Result) Then
  MessageBox(0, PChar('Nie można zamienić na liczbę:'#13+Str), '', 0);
End;

Ewentualnie zrobić tak:

Function ZamienNaLiczbe(Str: String): Integer;
Var NewStr: String;
    I: Integer;
Begin
 NewStr := '';
 For I := 1 To Length(Str) Do
  if Str[I] in ['0'..'9'] Then
   NewStr := NewStr+Str[I];
 if Length(NewStr) > 0 Then
  Result := StrToInt(NewStr) Else
  Result := 0;
End;

Funkcja podana wyżej najpierw wyciągnie wszystkie liczby, a potem dopiero zamieni je na integer.
Jest jeszcze masa sposobów, lecz te są najprostsze.
PS: dlaczego ludzie zaczynają programowanie od Delphi?
Potem pojawiają się takie dziwne kody.
Najpierw konsola+FPC, a potem okienka+Delphi.

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