* * * *

Privacy Policy

Blog italiano

Clicca qui se vuoi andare al blog italiano su Lazarus e il pascal.

Forum ufficiale

Se non siete riusciti a reperire l'informazione che cercavate nei nostri articoli o sul nostro forum vi consiglio di visitare il
Forum ufficiale di Lazarus in lingua inglese.

Lazarus 1.0

Trascinare un file nel programma
DB concetti fondamentali e ZeosLib
Recuperare codice HTML da pagina web
Mandare mail con Lazarus
Stabilire il sistema operativo
Esempio lista in pascal
File INI
Codice di attivazione
Realizzare programmi multilingua
Lavorare con le directory
Utilizzare Unità esterne
TTreeView
TTreeview e Menu
Generare controlli RUN-TIME
LazReport, PDF ed immagini
Intercettare tasti premuti
Ampliare Lazarus
Lazarus e la crittografia
System Tray con Lazarus
UIB: Unified Interbase
Il file: questo sconosciuto
Conferma di chiusura di un applicazione
Liste e puntatori
Overload di funzioni
Funzioni a parametri variabili
Proprietà
Conversione numerica
TImage su Form e Panel
Indy gestiore server FTP lato Client
PopUpMenu sotto Pulsante (TSpeedButton)
Direttiva $macro
Toolbar
Evidenziare voci TreeView
Visualizzare un file Html esterno
StatusBar - aggirare l'errore variabile duplicata
Da DataSource a Excel
Le permutazioni
Brute force
Indy 10 - Invio email con allegati
La gestione degli errori in Lazarus
Pascal Script
Linux + Zeos + Firebird
Dataset virtuale
Overload di operatori
Lavorare con file in formato JSON con Lazarus
Zeos ... dietro le quinte (prima parte)
Disporre le finestre in un blocco unico (come Delphi)
Aspetto retrò (Cmd Line)
Lazarus 1.0
Come interfacciare periferica twain
Ubuntu - aggiornare free pascal e lazarus
fpcup: installazioni parallele di lazarus e fpc
Free Pascal e Lazarus sul Raspberry Pi
Cifratura: breve guida all'uso dell'algoritmo BlowFish con lazarus e free pascal.
Creare un server multithread
guida all'installazione di fpc trunk da subversion in linux gentoo
Indice
DB concetti fondamentali e connessioni standard
Advanced Record Syntax
DB concetti fondamentali e DBGrid
DB concetti fondamentali e TDBEdit, TDBMemo e TDBText
Advanced Record Syntax: un esempio pratico
Superclasse form base per programmi gestionali (e non)
Superclasse form base per programmi gestionali (e non) #2 - log, exception call stack, application toolbox
Superclasse form base per programmi gestionali (e non) #3 - traduzione delle form
Superclasse form base per programmi gestionali (e non) #4 - wait animation
Un dialog per la connessione al database:TfmSimpleDbConnectionDialog
Installare lazarus su mac osx sierra
immagine docker per lavorare con lazarus e free pascal
TDD o Test-Driven Development
Benvenuto! Effettua l'accesso oppure registrati.
Aprile 16, 2024, 11:10:45 pm

Inserisci il nome utente, la password e la durata della sessione.

38 Visitatori, 1 Utente
 

Autore Topic: Array  (Letto 185 volte)

Riccardo Ferrari

  • Newbie
  • *
  • Post: 34
  • Karma: +0/-0
Array
« il: Febbraio 10, 2024, 05:54:51 pm »
Ecco dunque il tema che mi preme molto più del case dei nomi dei file.
Si tratta delle Array di AnsiString, ma il discorso vale per le Array di qualunque cosa.
Quando si dichiara un’Array dinamica, prima di iniziare a fare qualunque cosa devo stabilirne la dimensione.
Setlength(Array,Dword)
Come faccio a sapere PRIMA quando deve essere grande l’Array?
Infatti dopo aver elaborato i dati ed avuto la loro dimensione esatta, si rifà setlength con la dimensione giusta.
Non è possibile ovviare a ciò?
Ho un file di testo che leggo per intero, per poi elaborarlo in vario modo. Metto tutte le linee dentro un’Array. Ma quante sono le linee lo so solo dopo averlo letto. Ma devo dimensionare l’array prima di leggerlo. Per cui che fare?
1) si esagera, mettendo una setlength enorme, per poi ridurla dopo aver letto il file
2) come faccio da un po' di tempo, leggo il file di testo una prima volta solo per determinare il numero delle linee, dimensiono l’array e poi rileggo il file di testo per metterlo nell’array.
3) mettere una setlength un po’ di più del comune (ritenendo che una enorme comprometta le risorse del computer) però rischiando di andare in overflow (mi è successo)
Ringrazio quanti vorranno intervenire

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1266
  • Karma: +43/-0
  • Prima ascoltare, poi decidere
Re:Array
« Risposta #1 il: Febbraio 10, 2024, 06:57:18 pm »
Non puoi in alcun modo caricare un array (dinamico o no) con più dati rispetto alla sua capienza.
E non c'è modo di alimentare l'array "prima" in maniera che si autodimensioni.

Quello che si fà normalmente è leggere qualsiasi dato tramite un STREAM, poi vista la lunghezza dello stream si dimensiona l'array e vi si trasferiscono i dati.
Ci sono alcune funzioni che ritornano un array dinamico, però complesso. Un esempio sono le funzioni che ritornano una lista compatibile con TList.
Ma dietro c'è comunque una lettura e un successivo ridimensionamento "nascosto" al programmatore.

Ci sono poi componenti utili per leggere testo come TRichEdit, TMemo e simili.

P.S.: ci sono modi veloci per caricare array, sempre che non ci siano trasformazioni di dati e i tipi di dati siano esattamente IDENTICI tra i due contenitori.
Vedi la funzione MOVE: https://www.freepascal.org/docs-html/rtl/system/move.html, ma l'array comunque DEVE essere già dimensionato.

Tieni anche presente chein un array la memoria allocata è a blocchi, cioè ogni "riga" di un array (nel caso di array multidimensione) viene garantita allineata (cioè puoi usare il MOVE) ma tra una riga e un'altra non c'è garanzia di continuità.


« Ultima modifica: Febbraio 10, 2024, 07:07:14 pm da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

bonmario

  • Hero Member
  • *****
  • Post: 1300
  • Karma: +10/-1
Re:Array
« Risposta #2 il: Febbraio 10, 2024, 08:02:18 pm »
Ho un file di testo che leggo per intero, per poi elaborarlo in vario modo. Metto tutte le linee dentro un’Array. Ma quante sono le linee lo so solo dopo averlo letto. Ma devo dimensionare l’array prima di leggerlo. Per cui che fare?
1) si esagera, mettendo una setlength enorme, per poi ridurla dopo aver letto il file
2) come faccio da un po' di tempo, leggo il file di testo una prima volta solo per determinare il numero delle linee, dimensiono l’array e poi rileggo il file di testo per metterlo nell’array.
3) mettere una setlength un po’ di più del comune (ritenendo che una enorme comprometta le risorse del computer) però rischiando di andare in overflow (mi è successo)

Ciao,
non sono sicuro di aver capito la domanda, comunque, se è come ho capito, non devi per forza dimensionare l'array a priori, puoi aumentare di volta in volta la sua dimensione.

Qui un esempio in cui, leggendo un file di testo, andavo a salvarmi i dati in un array:

Codice: [Seleziona]
procedure TForm1.VerificaCsv(NomeCsv: String);
type TTipoPosizDate = array of Integer;
const ChrSost='^';
      ChrDaCerc=#0;
var St, StOrig, StrTestata:String;
    f:TextFile;
    ListaWrk:TStringList;
    PosizDate:TTipoPosizDate;
    VFPrimaRiga, VFFileDaElaborare, VFDataOk, VFPrimoErrore:Boolean;
    Idx, IdxArray:Integer;
begin
  //Inizializzazione variabili di lavoro
  VFPrimoErrore:=True;
  VFPrimaRiga:=True;
  VFFileDaElaborare:=True;

  AssignFile(f, UTF8ToSys(NomeCsv));
  FileMode:=CstApriFileSolaLett;
  try
    Reset(f);

    while (not Eof(f)) and
          VFFileDaElaborare do begin
      Readln(f, St);
      StOrig:=St;

      //Scompongo la stringa nei suoi elementi principali
      ListaWrk:=TStringList.Create;
      try
        ScomponiStringa(';', St, ListaWrk, True, False);

        //Se è la prima riga, valorizzo l'array in cui mi salvo le posizioni dei campi
        //di tipo data nel CSV
        if VFPrimaRiga then begin
          VFPrimaRiga:=False;

          StrTestata:=StOrig;

          PosizDate:=nil;
          IdxArray:=0;
          for Idx:=0 to ListaWrk.Count - 1 do begin
            St:=UpperCase(ListaWrk[Idx]);
            System.Delete(St, 1, Pos('_', St));
            if (Copy(St, 1, 4) = 'DATA') then begin
              SetLength(PosizDate, IdxArray + 1);
              PosizDate[IdxArray]:=Idx;
              Inc(IdxArray);
            end;
          end;

          //Se il file non ha nemmeno una data, è inutile proseguire !!!
          if (IdxArray = 0) then begin
            VFFileDaElaborare:=False;
          end;
        end else begin
          VFDataOk:=True;
          for Idx:=Low(PosizDate) to High(PosizDate) do begin
            if VFDataOk then begin
              if (not DataOk(ListaWrk[PosizDate[Idx]])) then begin
                VFDataOk:=False;
              end;
            end;
          end;

          //Se almeno una delle date non è corretta, lo segnalo
          if (not VFDataOk) then begin
            if VFPrimoErrore then begin
              VFPrimoErrore:=False;
              Memo1.Lines.Add('');
              Memo1.Lines.Add(NomeCsv);
              Memo1.Lines.Add(StrTestata);
            end;

            //Se il file contiene caratteri #0, lo segnalo
            if (Pos(ChrDaCerc, StOrig) > 0) then begin
              StOrig:=StringReplace(StOrig, ChrDaCerc, ChrSost, [rfReplaceAll]);
              Memo1.Lines.Add('    ==> La riga seguente conteneva caratteri #0, sostituiti con ' + ChrSost);
            end;
            Memo1.Lines.Add('  '+ StOrig);
          end;
        end;
      finally
        PulisciLista(ListaWrk, tpFree);
      end;
    end;
  finally
    CloseFile(f);
  end;
end;


In particolare, in questo pezzettino qui, all'inizio l'array è a nil, e la sua dimensione è 0.
Poi, per ogni dato buono che trovo, aumento di 1 la dimensione

Codice: [Seleziona]
          PosizDate:=nil;
          IdxArray:=0;
          for Idx:=0 to ListaWrk.Count - 1 do begin
            St:=UpperCase(ListaWrk[Idx]);
            System.Delete(St, 1, Pos('_', St));
            if (Copy(St, 1, 4) = 'DATA') then begin
              SetLength(PosizDate, IdxArray + 1);
              PosizDate[IdxArray]:=Idx;
              Inc(IdxArray);
            end;
          end;

Ciao, Mario

quack

  • Jr. Member
  • **
  • Post: 65
  • Karma: +7/-0
Re:Array
« Risposta #3 il: Febbraio 10, 2024, 08:50:45 pm »
Quando si tratta di file di testo solitamente uso le TStringList. Leggere e salvare è un attimo.
Certamente si può usare anche l'array dinamico, in ogni caso prima di scegliere tra array o lista bisogna
capire quale si adatta meglio alla tua situazione.

La tua era una domanda generica o hai un caso di esempio su cui devi lavorare ?
Se ci spieghi cosa devi fare è più facile risponderti.

Ciao
SO: Fedora\W10
Lazarus: Trunk\3.0
FPC: Trunk\3.2.2

Riccardo Ferrari

  • Newbie
  • *
  • Post: 34
  • Karma: +0/-0
Re:Array
« Risposta #4 il: Febbraio 10, 2024, 09:31:47 pm »
Ringrazio quanti hanno risposto.
Elaboro le vostre indicazioni.

 

Recenti

How To

Utenti
  • Utenti in totale: 785
  • Latest: gmax
Stats
  • Post in totale: 18769
  • Topic in totale: 2232
  • Online Today: 95
  • Online Ever: 900
  • (Gennaio 21, 2020, 08:17:49 pm)
Utenti Online
Users: 1
Guests: 38
Total: 39

Disclaimer:

Questo blog non rappresenta una testata giornalistica poiché viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge n. 62/2001.