Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Dynamische Arrays ... kleines Problem! (https://www.delphipraxis.net/74376-dynamische-arrays-kleines-problem.html)

sonicfire 2. Aug 2006 02:21


Dynamische Arrays ... kleines Problem!
 
Servus allerseits! :)

Ich habe schlicht und einfach nur die Frage...

Ich habe folgendes:
Delphi-Quellcode:
Test: Longint;
So, nun möchte ich einen Array erstellen und dem die Größe
von "Test" geben ... :
Delphi-Quellcode:
SetLength(MeinArray, Trunc(Test));
Egal, welche Werte sich in "Test" befinden, ich habe
das Gefühl das dies so nicht geht - bekomme immer exceptions. :(

Kann mir jemand einen Tipp geben?

(PS: Test MUSS LongInt sein ... oder muss ich das konvertieren? Irgendwie? :))

gmc616 2. Aug 2006 02:43

Re: Dynamische Arrays ... kleines Problem!
 
Hmm ... meine Glaskugel sagt:
Delphi-Quellcode:
var
  Test : longint;
  MeinArray : array of word;
begin
  Test := 12345;
  setlength(MeinArray,trunc(Test));
funktioniert.

Welche Exception bekommst du denn?
Ein bischen mehr Code würde uns sicher auch weiter helfen.

Luckie 2. Aug 2006 03:04

Re: Dynamische Arrays ... kleines Problem!
 
Warum trunc? Test ist doch schon ein Integer.

himitsu 2. Aug 2006 14:20

Re: Dynamische Arrays ... kleines Problem!
 
Zitat:

Kann mir jemand sagen, warum dies so nicht funktioniert?

Delphi-Quellcode: markieren
Delphi-Quellcode:
SetLength(LoopBuffer, Trunc(Header.DataBytes));

?

"LoopBuffer" ist ein offenes Array vom Typ SmallInt, während "Header.DataBytes" vom Typ LongInt ist und mir Werte wie z.b. "248316" liefert.

Aber wieso ist das so nicht machbar?
Gibt´s Array-Grenzen im Bezug auf Größe? (Obwohl ich mir das nicht vorstellen kann)

248316*SizeOf(SmallInt) = 485 KB sollte also kein Problem darstellen

Die Grenzen für dynamische Arrays liegen bei
High(Integer) div SizeOf(FeldGröße)
und natürlich dem zur Verfügung stehenden, zusammenhängenden, virtuellen Speicher.

also bei dir
$7FFFFFFF div 2 = maximal 1.073.741.823




Und ohne weiteren Code deinerseit kann dir keiner helfen ... das mit dem TRUNC wurde schon gesagt und sonst ist hier kein Fehler zu finden.

3_of_8 2. Aug 2006 14:32

Re: Dynamische Arrays ... kleines Problem!
 
Arrays sind nullbasiert.

Das erste Element steht nicht in Index 1, sondern in index 0. Das letzte Element steht also auch nicht in length(array), sondern in length(array)-1 bzw. high(array).

Vielleicht ist das das Problem.

Der_Unwissende 2. Aug 2006 14:56

Re: Dynamische Arrays ... kleines Problem!
 
Zitat:

Zitat von 3_of_8
Arrays sind nullbasiert.

Dynamische Arrays sind nullbasiert :warn:

Gruß Der Unwissende

sonicfire 2. Aug 2006 16:53

Re: Dynamische Arrays ... kleines Problem!
 
Danke, an alle! Das Problem konnte ich mittlerweile beheben! Aber wie das so ist - prompt hat man ein neues :wink: :

Beispiel:
Delphi-Quellcode:
LoopBuffer: array of SmallInt;
SetLength(LoopBuffer, Header.DataBytes);
LoopBuffer := 0;
(...)
Delphi-Quellcode:
BlockWrite(F, LoopBuffer, Length(LoopBuffer));
..bekomme ich grundsätzlich den EInOutError #1784 ... (das der zur Verfügung gestellte Puffer für diese Operation nicht gültig ist)
:shock:

Und da Frage ich mich nun, warum??

BlockWrite benötigt für "Count" (anzahl der Records, quasi) einen Wert vom Typ Integer. So. Mein "Length(LoopBuffer)" GIBT einen Integerwert zurück! (Hab ich bereits via Bildschirmausgabe getestet).

Wo zum Henker ist also das verdammte Problem hier? :wall: :gruebel:
:(

Der_Unwissende 2. Aug 2006 16:59

Re: Dynamische Arrays ... kleines Problem!
 
Zitat:

Zitat von sonicfire
Beispiel:
Delphi-Quellcode:
LoopBuffer: array of SmallInt;
SetLength(LoopBuffer, Header.DataBytes);
LoopBuffer := 0;
(...)

Du weißt einem Array of SmallInt eine 0 zu? Was genau soll das bezwecken?

Die Größe ist soweit auch nicht der Fehler. Versuch aber mal die Adresse des ersten Elements zu verwenden statt den Zeiger auf das Array:

Delphi-Quellcode:
BlockWrite(F, @LoopBuffer[0], Length(LoopBuffer));
Nebenbei bemerkt, Count sollte imho die Anzahl von Byte angeben, die geschrieben werden und hat nichts mit Records zu tun!

Gruß Der Unwissende

sonicfire 2. Aug 2006 17:15

Re: Dynamische Arrays ... kleines Problem!
 
Danke! :)

Mit dem ":= 0" - ööhm...dachte, so.... zur Initialisierung, quasi? :oops:

Hmm habs mit dem Pointer getestet, Allerdings kann ich es nicht kompilieren, bekomme dann immer die Fehlermeldung das er noch eine Variable benötigt... :?
Nun dachte ich wenn ich direkt LoopBuffer[0] angebe, würde er quasi bei Eintrag 0 starten... aber irgendwie.... ist dann nichts mehr in meinem WAV-File :mrgreen: :gruebel:

Flocke 2. Aug 2006 17:21

Re: Dynamische Arrays ... kleines Problem!
 
Das @ muss weg, das ist ein var-Parameter.
Zitat:

Zitat von Der_Unwissende
Delphi-Quellcode:
BlockWrite(F, LoopBuffer[0], Length(LoopBuffer));


sonicfire 2. Aug 2006 17:24

Re: Dynamische Arrays ... kleines Problem!
 
Huch, hab ich jetzt "^" und "@" verwechselt? ^ war doch ein Pointer? :)

Ja, und einfach nur mit "LoopBuffer[0]" - das habe ich versucht. Der Fehler ist endlich weg, aber das Resultat: Stille im WAV-file :gruebel:

3_of_8 2. Aug 2006 17:28

Re: Dynamische Arrays ... kleines Problem!
 
Jein.

Delphi-Quellcode:
type
  PInteger = ^Integer;
Hier: ^ vor einem Typ zur Deklaration eines Zeigertyps

Delphi-Quellcode:
var I: Integer;
    PI: PInteger;
begin
I:=PI^;
end;
Hier: ^ nach einem Pointer zur Dereferenzierung eines Zeigers

Delphi-Quellcode:
var I: Integer;
    PI: PInteger;
begin
PI:=@I;
end;

Hier: @ vor einer Variable zur Erzeugung eines Pointers.

DGL-luke 2. Aug 2006 17:29

Re: Dynamische Arrays ... kleines Problem!
 
@sonicfire:

Zum Initialisieren eines arrays würd ich ZeroMemory hernehmen.

sonicfire 2. Aug 2006 19:49

Re: Dynamische Arrays ... kleines Problem!
 
Danke an alle erstmal soweit! :)

Dummerweise gibts schon wieder ein neues Problem ;) Hachja....*seufz*

Wenn ich den Inhalt vom LoopBuffer Array (SmallInt´s) in mein WAV-file schreiben
will, unter Verwendung von:

Delphi-Quellcode:
BlockWrite(F, LoopBuffer[0], Header.DataBytes);
...kommt nur murks bei raus! seufz...!
Man höre hier: annoying.wav

Bild dazu (Code)...achtung, newbie-code ;)
http://www.prodyon-virtual-gear.com/wrongcode.jpg

sonicfire 2. Aug 2006 21:16

Re: Dynamische Arrays ... kleines Problem!
 
http://www.prodyon-virtual-gear.com/wrongcode2.jpg
wie man sieht, wenig code - aber irgendwas muss wohl total falsch sein?

fwsp 2. Aug 2006 21:18

Re: Dynamische Arrays ... kleines Problem!
 
man hätte auch den code als text posten können...

sonicfire 2. Aug 2006 21:48

Re: Dynamische Arrays ... kleines Problem!
 
Nicht persönlich nehmen, aber man hätte diesen Beitrag auch lassen können ;) Denn das hilft mir nicht.

sonicfire 2. Aug 2006 22:14

Re: Dynamische Arrays ... kleines Problem!
 
Seufz... wer mir mit dem Code hilft, bekommt 10 Euro :roll: :wink:

BlackJack 2. Aug 2006 22:20

Re: Dynamische Arrays ... kleines Problem!
 
ein smallint ist 2 bytes gross, also musst du auch doppelt so viele bytes schreiben wie Header.DataBytes angibt:
Code:
BlockWrite(F, LoopBuffer[0], Header.DataBytes*SizeOf(SmallInt));
und steig zum arbeiten mit dateien lieber auf TFileStream um, kommt besser ;)

edit: Kontonummer kommt dann per PN :P

sonicfire 2. Aug 2006 22:25

Re: Dynamische Arrays ... kleines Problem!
 
Danke, BlackJack! :) Leider hat das nur nichts geändert :(

BlackJack 2. Aug 2006 22:28

Re: Dynamische Arrays ... kleines Problem!
 
hast du dran gedacht das bei allen BlockReads/BlockWrites zu ändern? weil sowohl Buffer als auch LoopBuffer sind arrays of SmallInt, aber du liest/schreibst immer Length() viele bytes aus, aber du musst immer Length() SmallInts auslesen :warn:

sonicfire 2. Aug 2006 22:31

Re: Dynamische Arrays ... kleines Problem!
 
Zitat:

Zitat von BlackJack
hast du dran gedacht das bei allen BlockReads/BlockWrites zu ändern? weil sowohl Buffer als auch LoopBuffer sind arrays of SmallInt, aber du liest/schreibst immer Length() viele bytes aus, aber du musst immer Length() SmallInts auslesen :warn:

Naja, das merkwürdige ist - lasse ich den letzten "Test" unten weg, ist das Ergebnis 1A! Genau DESWEGEN versteh ich ja die Welt nicht mehr :wall: Denn das ist quasi derselbe Schritt, selber Buffer, selbe Datentypen usw .... :)

sonicfire 3. Aug 2006 13:46

Re: Dynamische Arrays ... kleines Problem!
 
:lol: :roll: Oh man, und jetzt weiss keiner mehr weiter ... *grins*.
Das kann doch alles nicht sein :x Der Code müsste eigtl. doch funzen - tut es aber nicht ... seufz

sonicfire 3. Aug 2006 16:04

Re: Dynamische Arrays ... kleines Problem!
 
Soll ich demjenigen der das zum laufen bekommt 100 Euro zahlen? Lol! Gibts dann eine Antwort?
Man, echt - ich glaub das alles nicht ;) Kann doch nicht sein das ich hier ein unlösbares Problem habe.....! NADA!

EDatabaseError 3. Aug 2006 16:05

Re: Dynamische Arrays ... kleines Problem!
 
:roll: nich soviel pushen

DGL-luke 3. Aug 2006 16:50

Re: Dynamische Arrays ... kleines Problem!
 
Arrays speichern/laden? Nichts leichter als das:

Delphi-Quellcode:

type
  TMyTypeArray = array of TMyType; //TMyType durch fundamentalen typen ersetzen (z.B. Integer, oder ein record mit fudamentalen Typen)


procedure SaveToFile(Filename: string; Value: TMyTypeArray);
begin
  with TFilestream.Create(FileName, fmOpenRead) do
    try
      WriteBuffer(Value,length(Value) * sizeof(TMyType));
    finally
      Free;
    end;
end;

procedure SaveToFileAppend(Filename: string; Value: TMyTypeArray);
begin
  with TFilestream.Create(FileName, fmOpenWrite) do
    try
      Position := Size;
      WriteBuffer(Value,length(Value) * sizeof(TMyType));
    finally
      Free;
    end;
end;


procedure LoadFromFile(FileName: string; out Value: TMyTypeArray;Start: Integer = 0);
begin
  with TFilestream.Create(FileName, fmOpenRead) do
    try
      Position := Start;
      setlength(Value, Size-Position);
      ReadBuffer(Value,length(Value));
    finally
      Free;
    end;
end;
Was du jetzt tun musst:

1. Diesen Code in dein Programm kopieren
2. TMyType (alle Vorkommen!) durch SmallInt ersetzen (allerdings solltest du anstatt "SmallIntArray" evtl. "TSmallIntArray" erwägen, das ist so üblicher)
3. Deinen LoopBuffer als SmallInt deklarieren

Der dritte Schritt ist der wichtigste, der Compiler reisst dir sonst den Arsch auf!

Dann kannst du (gerne auch in SaveTheWave) einfach SaveToFileAppend aufrufen, um an deinen Header (für den du das Verfahren mit dem FileStream gerne übernehmen kannst, du könntest auch z.B. den zusätzlichen Parameter "Header" ins savetofile einfügen, und den zuerst schreiben).

Wenn dir Delphi-Referenz durchsuchenwith ... do und Delphi-Referenz durchsuchentry ... finally ... end nichts sagen, solltest du in deine Delphi-Hilfe schauen, da müsste einiges drüber finden.

sonicfire 3. Aug 2006 16:54

Re: Dynamische Arrays ... kleines Problem!
 
@EDatabaseError: Verzeihung! :oops:

@DGL-Luke: Vielen Dank!! :) Mal sehen, inwieweit ich das so hinbekomme ;) Wofür steht eigtl. das ewige "T"? :stupid:
"T"ype? *grins*

DGL-luke 3. Aug 2006 17:04

Re: Dynamische Arrays ... kleines Problem!
 
Jop. Ist bei Pascal einfach Standard, damit man Typen besser von Variablen unterschieden kann.

sonicfire 3. Aug 2006 18:26

Re: Dynamische Arrays ... kleines Problem!
 
@DGL-Luke: Noch eine (blöde?) Frage ? Wie komme ich über TStream eigentlich an meine WAV-Daten heran um sie zu manipulieren?

Quasi:
For b=0 to endeVomBuffer
"WaveData.Buffer[b] := wasauchimmer"

? :)

DGL-luke 3. Aug 2006 18:41

Re: Dynamische Arrays ... kleines Problem!
 
Naja...

Delphi-Quellcode:
procedure WasMachenMitWavVonDatei(filename: string);
var Wavbuffer: TSmallIntArray;
    i: Integer;
begin
//laden
LoadFromFile(filename, Wavbuffer, sizeof(TWavHeader)+1);
//was machen
for i := 0 to high(Wavbuffer) do
  Wavbuffer[i] .....
end;
Das sizeof(TWavHeader) mache ich, damit er erst nach dem header lädt. Ich habe in dienem Quellcode ja gesehen, dass du zuerst einen Header schreibst. Den überspringe ich damit.

sonicfire 3. Aug 2006 18:48

Re: Dynamische Arrays ... kleines Problem!
 
Dank Dir! :)

DGL-luke 3. Aug 2006 18:57

Re: Dynamische Arrays ... kleines Problem!
 
Kein Problem.

Streams sind zum verschieben von Datenmengen auf jeden Fall besser als file of-Konstruktionen.

Es gibt übrigens auch Delphi-Referenz durchsuchenTMemoryStream und Delphi-Referenz durchsuchenTResourceStream.

sonicfire 3. Aug 2006 19:12

Re: Dynamische Arrays ... kleines Problem!
 
Hmmm.. bekomme andauernd "undeclared Identifier" .... sehr merkwürdig, die sind doch definiert...

DGL-luke 3. Aug 2006 19:15

Re: Dynamische Arrays ... kleines Problem!
 
Zeig doch ein wenig Code.

Am besten den, in dem der Fehler auftritt

sonicfire 3. Aug 2006 19:22

Re: Dynamische Arrays ... kleines Problem!
 
Unter "Implementation" :
Delphi-Quellcode:
Type
    TSmallIntArray = Array of SmallInt;
end;
..muss hier kein record hin?(Hier habe ich garantiert noch etwas verwechselt) :oops:

Ansonsten:
Delphi-Quellcode:
(...)

   procedure SaveWavFileClick(Sender: TObject);
    procedure DisableItems(Status: Boolean);
    procedure KeyNoteClickCheck(Sender: TObject);
    Procedure LoadTheWave(FileName: String; out Value: TSmallIntArray; Start: Integer = 0);

  private
    { Private declarations }
  public
   KeysToRecord: Array[0..11] of Integer;
   function ValidateInput(Itemobject: String; minval, maxval: Integer): String;
    { Public declarations }
  end;

(...)
Procedure LoadTheWav: Identifier redeclared usw

:|

DGL-luke 3. Aug 2006 19:28

Re: Dynamische Arrays ... kleines Problem!
 
1. der type muss ins interface, nicht in implementation

2. es sollte in ein EINER unit nur EINMAL type geben ! alles andere führt potenziell zu schlimmen Sachen....

3. identifier redeclared kommt, weil du es im implementation abschnitt deklarierst, im interface aber schon verwedest... ja, die fehlermeldung ist ein wenig irreführend...

sonicfire 3. Aug 2006 19:35

Re: Dynamische Arrays ... kleines Problem!
 
Vielen Dank!! :)

EDIT: Hab es :oops: :lol:

sonicfire 3. Aug 2006 20:15

Re: Dynamische Arrays ... kleines Problem!
 
Okayyyy.... alllso einmal muss ich doch noch was fragen! :oops:

Und zwar:
Delphi-Quellcode:
Procedure TForm1.LoadTheWave(FileName: String; out Value: TSmallIntArray;Start: Integer = 0);
begin
  with TFilestream.Create(Filename, fmOpenRead) do
    try
      Position := Size;
      setlength(Value, Size-Position);
      ReadBuffer(Value,length(Value));
    finally
      Free;
    end;
end;

Procedure TForm1.SaveTheWave(Filename: string; Value: TSmallIntArray);
begin
  with TFileStream.Create(Filename, fmOpenWrite) do
    try
      WriteBuffer(Value,length(Value)*sizeof(SmallInt));
    finally
      Free;
    end;
end;

Procedure TForm1.ProcessWave(FileName: String);
var
    Wavbuffer: TSmallIntArray;
    Header: TWaveHeader;
    i: Integer;

begin
  LoadTheWave(Outputfile.Text, Wavbuffer, sizeof(Header)+1); //laden des waves
  for i := 0 to high(Wavbuffer) do // testweise stille einfügen
  begin
    Wavbuffer[i] := 0;
  end;
  SaveTheWave(Outputfile.Text, Wavbuffer);
end;
Siehe "ProcessWave(FileName: String);"

Ich lade also das wav-file, modifiziere es und speichere es wieder ...
allerdings hat sich rein gar nichts im WAV file verändert? :)

Der_Unwissende 3. Aug 2006 20:30

Re: Dynamische Arrays ... kleines Problem!
 
Zitat:

Zitat von sonicfire
Delphi-Quellcode:
Procedure TForm1.LoadTheWave(FileName: String; out Value: TSmallIntArray;Start: Integer = 0);
begin
  with TFilestream.Create(Filename, fmOpenRead) do
    try
      Position := Size;
      setlength(Value, Size-Position);
      ReadBuffer(Value,length(Value));
    finally
      Free;
    end;
end;

Schau dir mal an was du hier tust! Du setzt Position := Size und dann die Länge von Value auf Size - Position, anders gesagt, du setzt die Länge von Value auf 0.
Wenn du 0 Byte zu schreiben hast, nun ja, dann wird natürlich auch nie irgendwas geschrieben...

Gruß Der Unwissende

[EDIT]
PS: Du solltest deine FileStreams noch etwas anders öffnen. Wenn du etwas zum Lesen öffnest, solltest du eine Schreibsperre setzen (sonst könntest du irgendwann das Problem haben, dass jmd. schreibt während du liest) und wenn du schreibst, dann kannst du gleich exklusiv sperren.
Delphi-Quellcode:
// zum Lesen:
TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);

// zum Schreiben:
TFileStream.Create(FileName, fmOpenRead or fmShareExclusive);
[/EDIT]

sonicfire 3. Aug 2006 20:49

Re: Dynamische Arrays ... kleines Problem!
 
Danke! Aber wieso ein "or" dazwischen? Nicht: fmOpenRead, fmSowieso?


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:38 Uhr.
Seite 1 von 2  1 2      

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