25. februar 2005 - 15:02Der er
14 kommentarer og 1 løsning
Problem med funktioner
Jeg har følgende 3 funktioner (som jeg for i øvrigt har fået herinde fra) men når jeg kører dem bliver der af en eller anden grund lagt 4398512 til det resultat de skal vise.
Her er funktionerne:
function AntalOrd(Text: String): Integer; var i_pos: Integer; // Position of search pattern in string i_count: Integer; // Counter s_temp: String; // Temporary workstring begin s_temp := Trim(Text); repeat i_pos := Pos(' ', s_temp); if i_pos > 0 then begin Inc(i_count); s_temp := Trim(Copy(s_temp, i_pos + 1, Length(s_temp) - i_pos)); end // if i_pos > 0 else begin Inc(i_count); end; // else until (i_pos = 0); result := i_count; end; // WordsInText
function LangeOrd(Text: String): Integer; var i_pos: Integer; // Position of search pattern in string i_count: Integer; // Counter s_temp: String; // Temporary workstring begin s_temp := Trim(Text); repeat i_pos := Pos(' ', s_temp); if i_pos > 0 then begin if i_pos > 6 then begin Inc(i_count); end; // if i_pos > i_length s_temp := Trim(Copy(s_temp, i_pos + 1, Length(s_temp) - i_pos)); end // if i_pos > 0 else begin if AntalPunktummer(s_temp) > 0 then begin if Length(s_temp) > 6 then begin Inc(i_count); end; // if Length(s_temp) > i_length end // if PeriodesInText(s_temp) > 0 else begin if Length(s_temp) >= 6 then begin Inc(i_count); end; // if Length(s_temp) >= i_length end; // else end; // else until (i_pos = 0); result := i_count; end; // LongWordsInText
function AntalPunktummer(Text: String): Integer; var i_pos: Integer; // Position of search pattern in string i_count: Integer; // Counter s_temp: String; // Temporary workstring begin s_temp := Trim(Text); repeat i_pos := Pos('.', s_temp); if i_pos > 0 then begin Inc(i_count); s_temp := Trim(Copy(s_temp, i_pos + 1, Length(s_temp) - i_pos)); end; // if i_pos > 0 until (i_pos = 0); result := i_count; end; // PeriodesInText
De bliver brugt på denne måde (skal siges Texteditor er en anden TForm):
Prøv at gøre det Delphi advarer dig om at du ikke har gjort ;)
Sæt en i_count := 0; ind i starten af hver af dine funktioner.
Når du opretter en variabel, så kan du aldrig være sikker på at den indeholder 0 når du skal bruge den første gang, så derfor er det altid en god idé at nulstille sine variabler inden man skal bruge dem :)
Gad ikke lige flyve igang med ovenstående, men lavede i stedet nedenstående alternativer:
function AntalOrd(const aText : string) : integer; var OrdListe : TStringList; begin result := 0; OrdListe := TStringList.Create; try OrdListe.Delimiter := #32; // Sgu da elegant, ikke? OrdListe.DelimitedText := aText; result := OrdListe.Count; finally OrdListe.Free; end; end;
function LangeOrd(const aText : string; const aLangtOrdLaengde : integer) : integer; var i : integer; OrdListe : TStringList; begin result := 0; OrdListe := TStringList.Create; try OrdListe.Delimiter := #32; OrdListe.DelimitedText := aText; for i := 0 to OrdListe.Count - 1 do if length(OrdListe[i]) >= aLangtOrdLaengde then result := result + 1; finally OrdListe.Free; end; end;
function AntalPunktummer(const aText: string): integer; var i : integer; begin result := 0; for i := 1 to length(aText) do if aText[i] = '.' then result := result + 1; end;
// Alternativt denne her:
function AntalPunktummer(const aText : string) : integer; var OrdListe : TStringList; begin OrdListe := TStringList.Create; try OrdListe.Delimiter := '.'; OrdListe.DelimitedText := aText; result := OrdListe.Count; finally OrdListe.Free; end; end;
Drop alternativet (den sidst funktion). Den regner også mellemrummene som adskillelse selvom jeg har sagt at det er punktum der tæller (1 punktion og funktionen returnerer antal ord + punktum)!
Men tænkte lige på hvorfor man skriver const aText : string altså hvorfor skriver du const foran?
Og lige en anden ting hvis du ved det: Hvordan tjekker jeg om et tegn fra en string er et bogstav uden at gøre sådan: if string[i] = a or if string[i] = b osv...
Mener man kan gøre noget i stil med if string[i] = [a...å] men kan ikke huske hvordan
Kan ikke lige helt huske det med const, men det er vist noget med om man må/kan ændre indholdet af den variabel der bliver sendt med.
Mht. det andet, så kan du bruge nedenstående eksempel:
procedure TForm1.Button1Click(Sender: TObject); var tmpstr: String; i: Integer; begin tmpstr := 'dA2s'; For i := 1 To Length(tmpstr) Do Begin If tmpstr[i] in ['a'..'å', 'A'..'Å'] Then ShowMessage(tmpstr[i] + ' = Bogstav') Else ShowMessage(tmpstr[i] + ' = Noget andet'); End; end;
"Const" har den effekt, at parameteren ikke kan ændres inde i scope (funktion/procedure). Desuden er måden som data overføres på, optimeret. Det er hurtigere end at angive ingenting. Her bliver strengen kopieret over i en ny streng og den slags kan tage tid (dog svinehurtigt på dagens maskiner). Jeg tror ikke, men er langtfra sikker, at der sker kopiering med "const" og antager at det er en form for read-only version af "var" hvor pointeren til parameteren sendes over, call-by-ref, fremfor call-by-value.
Desuden findes der også de sjældent brugte "in" og "out" der indikerer at parameteren er noget der kun bruges som input eller at det er en værdi der returneres. Tror mest de er med for at øge læsbarheden af ens kode.
Sorry snowball men dit første svar virkede ikke men det gjorde hrc's derimod. Og havde helt glemt dit svar på da jeg spurgte hvordan man kunne tælle bogstaver. Men er det ikke muligt at acceptere endnu et svar efter et er accepteret? For synes da bestemt du skal have point for svaret på antal bogstaver.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.