Newsgroup: it.comp.lang.delphi
Titolo: Stringhe stringate

Salve gente,
  ho un piccolo problema.  Chi mi puo' aiutare?
Vi espongo la questione.
Devo scrivere su file una struttura dati del tipo:
type tdato=record
	       nome:string;
	       percorso:string;
                          tipo:0..1
	   end	 
var  dato:tdato;
il file e' del tipo:
 
f:file;
rewrite(f,1);
Come faccio a scrivere correttamente la variabile <dato> in un sol
colpo?
Stavo pensando a 
      blockwrite(f,dato,sizeof(tdato)) 
ma vedo che e' gia sbagliata in partenza. Suggerimenti?
~Guybrush~

 ma vedo che e' gia sbagliata in partenza. Suggerimenti?
sui file binari sono molto arrugginito...
pero' penso che usando un
var
 f: file of tdato;
 Write(F,dato);
si possa fare... prova
Ciao,
Alan Solo

si possa fare... prova
si qualcosa del genere si puo' fare, ma le stringhe in questi casi danno
comunque problemi. se puoi sostituiscile con stringhe a lunghezza fissa:
type tdato=record
       nome:string[100];
       percorso:string[150];
                          tipo:0..1
   end
mi pare che una stringa a lunghezza fissa occupi 1+lenght byte.
gia' che ci sei definisci il tipo enumerato
type TTipo=(tPrimoTipo, tSecondoTipo);
per la variabile tipo. E' + bello del tipo intervallo che hai usato :)
{MSX}

 Write(F,dato);
Un attimo... l'idea e' buona ma ci sono 2 piccoli problemi:
-in realta' i dati che devo registrare non sono tutti dello stesso
tipo. Ma a parte questo il problema principale e' che le STRING che
sono prensenti nel dato fanno sbroccare il tutto.
type tdato=record
	       nome:string;
	       percorso:string;
                          tipo:0..1
	   end	
Secondo questa struttura il write scriverrebbe a 9 byte a botta (4byte
per string piu' un byte per il  tipo <0..1>). Pero' le stringhe
potrebbero contenere ad esempio una 100byte l'laltra 200byte....
 
~Guybrush~

per la variabile tipo. E' + bello del tipo intervallo che hai usato :)
Cioe'? Bello in che senso? Non e' la stessa cosa (al livello della
funzione)? Dai spiegami che sono curioso anche se e' una cavolata...
:-)
~Guybrush~

 textfile)
Semplicemente non puoi usare il tipo string se vuoi salvare un record.
Un'alternativa, se non ne puoi fare a meno, è quella di non usare record, ma
scrivere sul file delle cose di questo tipo:
- un intero che ti dice la lunghezza della prima stringa
- la prima stringa
- un intero che ti dice la lunghezza della seconda stringa
- la seconda stringa
- un intero che indica il tipo
Ovviamente una struttura di questo tipo non è assolutamente ottimizzata, per
leggere l'i-esimo "record" devi scorrere tutto il file per sapere
esattamente dove inizia.
La puoi ottimizzare usando due file: nel primo ci metti un record di questo
tipo:
type TIndice=record
  inizioStringa1:integer;
  lunghezzaStringa1:integer;
  inizioStringa2:integer;
  lunghezzaStringa2:integer;
  tipo:0..1;
end;
inizioStringa1 indica l'offset nel secondo file dove inizia la stringa1,
lunga lunghezzaStringa1 caratteri, e lo stesso per stringa2. In questo modo
per leggere l'i-esima stringa, tiri fuori l'i-esimo record dal primo file e
ne trai le informazioni per leggere dal secondo file.
Ciao
Ruggero

:-)
Diciamo che quando hai una variabile come tipo, che assume valori logici,
piuttosto che dare un valore numerico e' meglio assegnare un nome...
Ho visto che i campi del tuo record sono nome e percorso, immagino che si
parli di file e quindi tipo potrebbe indicare se e' un file (0) o una
directory (1).
in questo caso scrivere
tipo=(tFile, tDirectory);
e' piu' chiaro e piu' leggibile di
tipo: 1..0
nel programma scriverai tipo:=tDirectory .. si capisce di piu' !
Cosi' allo stesso modo e' meglio:
Seme=(sCuori, sQuadri, sPicche, sFiori);
piuttosto che
Seme: 0..3
tra l'altro puoi ottenere il numero d'ordine con Ord()
ord(sQuadri)  // ritorna 1
Ovviamente i tipi enumerati vengono poi tradotti dal compilatore in tipi
intervallo, quindi dal punto di vista della ottimizzazione non c'e' alcuna
differenza.

textfile)
Se l'esclusione dei textfile e' imperativa, puoi pensare di usare lo
streaming di Delphi (nel vecchio formato binario). Invece di usare un
record, usa un discendente dalla prima classe che supporta lo streaming
(TPersistent).
Vedi l'help, in particolare l'esempio di TPersistent.DefineProperties.
Saluti
Paolo Arosio

 comunque problemi. se puoi sostituiscile con stringhe a lunghezza fissa:
caspita, non l'avevo neanche vista la stringa,
io userei le stringhe a lunghezza fissa (come gia' suggerito)
o magari provare anche con i pchar (stringhe null terminated)
ma cmq di grandezza fissa (255 ad es. tanto le string non ne possono
contenere di piu')... l'unica cosa e' lo "spreco" di spazio...
...o se usi un DB usare i varchar e non pensarci piu' ;)
Ciao,
Alan Solo