Differenze tra le versioni di "Ottenere i "reali" valori numerici da una lettura di tipo Stringa di un flusso di dati"

Da Gambas-it.org - Wikipedia.
(Creata pagina con 'Per varie ragioni a volte può essere necessario effettuare una lettura di tali dati come tipo ''Stringa''. Ciò può risultare necessario in modo particolare quando si devono...')
 
 
(11 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
Per varie ragioni a volte può essere necessario effettuare una lettura di tali dati come tipo ''Stringa''. Ciò può risultare necessario in modo particolare quando si devono leggere da un file o altro flusso due o più dati che rappresentano per noi significativi, reali valori numerici. In tal caso, quindi, la stringa, ottenuta dalla lettura del flusso di dati, contiene due più valori numerici di qualsiasi tipo (''Short'', ''Integer'', etc.), che dovranno essere riconvertiti dall'attuale rappresentazione di tipo stringa alla rappresentazione di tipo numerale.
+
Per varie ragioni a volte può essere necessario effettuare una lettura di taluni dati come tipo ''Stringa'', pur non necessariamente appartenendo ad un file di testo. Ciò può risultare utile in modo particolare quando si devono leggere da un file o altro flusso due o più dati che rappresentano per noi significativi, reali valori numerici. In tal caso, quindi, la stringa, ottenuta dalla lettura del flusso di dati, contiene due più valori numerici di qualsiasi tipo (''Short'', ''Integer'', etc.), che ovviamente dovranno essere riconvertiti dall'attuale rappresentazione di tipo stringa alla rappresentazione di tipo numerale per ottenenre i loro originari e reali valori.
  
 +
 +
===Soluzione se i valori sono di tipo ''Byte''===
 
Se i valori numerali possono essere espressi dal tipo ''Byte'', allora per trasformare ogni carattere della stringa, ottenuta dalla precedente lettura del flusso, nel corrispondente ''reale'' valore numerico di tipo ''Byte'' si potrà utilizzare molto agevolmente il metodo ''.FromString()'' appartenente alla Classe ''Byte[]'':
 
Se i valori numerali possono essere espressi dal tipo ''Byte'', allora per trasformare ogni carattere della stringa, ottenuta dalla precedente lettura del flusso, nel corrispondente ''reale'' valore numerico di tipo ''Byte'' si potrà utilizzare molto agevolmente il metodo ''.FromString()'' appartenente alla Classe ''Byte[]'':
 
 
 
  Byte[].FromString(stringa) As Byte[]
 
  Byte[].FromString(stringa) As Byte[]
che riempirà, quindi, gli elementi di una variabile vettoriale di tipo ''Byte[]'' dei valori numerici ottenuti dalla conversione di ogni caratere della stringa.
+
che riempirà, quindi, gli elementi di una variabile vettoriale di tipo ''Byte[]'' dei valori numerici ottenuti dalla conversione di ogni carattere della stringa.
 +
 
 +
Si procederà alla lettura del valore, contenuto da ciascun elemento del vettore di tipo ''Byte[]'', nelle modalità consuete preferite.
  
  
Nei restanti casi, invece, sarà necessario creare una variabile di tipo ''Puntatore'' con la funzione ''Alloc()'', che avrà come parametro la variabile stringa contenente i dati ottenuti dalla precedente lettura del flusso.  
+
===Soluzione se i valori sono di tipo avente dimensione superiore al ''Byte''===
 +
Nei restanti casi si potrà agire con due modalità.
  
Successivamente si provvederà a dereferenziare la variabile ''Puntatore'', per poter ottenere i ''reali'' valori numerici.
 
<BR>Se il valore da ottenere è soltanto uno, allora la dereferenziazione potrà avvenire mediante le specifiche funzioni fornite da Gambas (''Short@()'', ''int@()'', etc.).
 
  
Se la stringa contiene più valori numerici da ricavare, allora si dovrà procedere con la dereferenziazione mediante i ''Memory Stream''.
+
====1<SUP>a</sup> modalità====
<BR>Facciamo un esempio di quest'ultimo caso:
+
In questa modalità si terrà conto della posizione di ciascun byte all'interno della sua rappresentazione esadecimale.
 +
<BR>Facciamo un esempio, ipotizzando che il file sia costituito dai seguenti 10 byte:
 +
''<FONT color=#B22222>56 34 12 00</font> <FONT color=darkgreen>44 33 22 11</font> <FONT color=#B22222>99 00</font>''
 +
che rappresentano in successione due Interi ed uno Short:
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
  Dim fl As File
 
 
   Dim s As String
 
   Dim s As String
  Dim p As Pointer
 
  Dim st As Stream
 
 
   Dim i1, i2 As Integer
 
   Dim i1, i2 As Integer
 
   Dim sh As Short
 
   Dim sh As Short
  Dim l As Long
 
 
    
 
    
    
+
   s = File.Load("''/percorso/del/file/da/leggere''")
  fl = Open "''/percorso/del/file o flusso/da/leggere" For Read
+
 +
<FONT Color=gray>' ''Tenendo conto che il valore è rappresentato in "Little-Endian":''</font> <SUP>&#091;[[#Note|nota 1]]&#093;</sup>
 +
  i1 = Asc(s, 1)
 +
  i1 += Asc(s, 2) * 256        <FONT Color=gray>' ''&0100''</font>
 +
  i1 += Asc(s, 3) * 65536      <FONT Color=gray>' ''&010000''</font>
 +
  i1 += Asc(s, 4) * 16777216  <FONT Color=gray>' ''&01000000''</font>
 +
 +
  i2 = Asc(s, 5)
 +
  i2 += Asc(s, 6) * 256
 +
  i2 += Asc(s, 7) * 65536
 +
  i2 += Asc(s, 8) * 16777216
 
   
 
   
<FONT color=gray>' ''Leggiamo dal flusso e salviamo i dati nella variabile di tipo stringa "s":''</font>
+
  sh = Asc(s, 9)
  Read #fl, s, -256
+
  sh += Asc(s, 10) * 256
 
   
 
   
<FONT color=gray>' ''Dalla variabile stringa "s" generiamo una variabile di tipo "Puntatore" mediante la funzione "Alloc()":''</font>
+
  Print i1
  p = Alloc(s)
+
  Print i2
 +
  Print sh
 
   
 
   
  <FONT color=gray>' ''Quindi passiamo alla dereferenziazione della variabile di tipo "Puntatore":''</font>
+
  '''End'''
  st = Memory p For Read
+
 
 +
 
 +
====Uso di una variabile di tipo ''Puntatore''====
 +
Questa modalità prevede la crazione di una variabile di tipo ''Puntatore'' con la funzione ''VarPtr()'', che avrà come parametro la variabile stringa contenente i dati ottenuti dalla precedente lettura del flusso.
 +
 
 +
Successivamente si provvederà a dereferenziare la variabile ''Puntatore'' mediante le specifiche funzioni fornite da Gambas (''Short@()'', ''int@()'', etc.), per poter ottenere i ''reali'' valori numerici.
 +
 
 +
 
 +
Facciamo un esempio, ipotizzando che il file sia costituito dai seguenti 18 byte:
 +
''<FONT color=#B22222>44 44 44 00</font> <FONT color=darkgreen>33 33 33 00</font> <FONT color=#B22222>22 00</font> <FONT color=darkgreen>11 11 11 11 11 11 11 00</font>''
 +
che rappresentano in successione due Interi, uno Short ed un Long.
 +
 
 +
Per ricavare i numeri dei predetti tipi rappresentati da quei byte, possiamo procedere come segue:
 +
Private s As String
 
   
 
   
<FONT color=gray>' ''Leggiamo dalla variabile di tipo "Stream" (ad esempio se sappiamo che la sequenza dei valori nel flusso è come appresso):''</font>
 
  Read #st, i1
 
  Read #st, i2
 
  Read #st, sh
 
  Read #st, l
 
 
   
 
   
  <FONT color=gray>' ''Infine, vediamo in console i "reali" valori numerici:''</font>
+
  '''Public''' Sub Main()
  Print i1, i2, sh, l
 
 
   
 
   
 +
  Dim p As Pointer
 +
  Dim i1, i2 As Integer
 +
  Dim sh As Short
 +
  Dim l As Long
 +
 
 +
<FONT color=gray>' ''Leggiamo il file come testo e salviamo i dati nella variabile di tipo stringa "s":''</font>
 +
  s = File.Load("<FONT color=gray>''/percorso/del/file/da/leggere''</font>")
 
   
 
   
  <FONT color=gray>' ''Va in chiusura:''</font>
+
  <FONT color=gray>' ''Dalla variabile stringa "s" generiamo una variabile di tipo "Puntatore" mediante la funzione "VarPtr()":''</font>
  st.Close
+
  p = VarPtr(s)
  Free(p)
 
  fl.Close
 
 
   
 
   
 +
<FONT color=gray>' ''Infine, vediamo in console i "reali" valori numerici, dereferenziando il Puntatore tenendo conto dei byte di memoria occupati da ciascun tipo di valore:''</font>
 +
  Print Int@(p)
 +
  Print Int@(p + 4)
 +
  Print Short@(p + 8)
 +
  Print Long@(p + 10)
 +
     
 
  '''End'''
 
  '''End'''
 +
 +
 +
 +
=Note=
 +
[1] Se fosse rappresentato, invece, in "Big-Endian", la conversione sarebbe:
 +
i = Asc(s, 1) * 16777216  <FONT Color=gray>' ''&01000000''</font>
 +
i += Asc(s, 2) * 65536    <FONT Color=gray>' ''&010000''</font>
 +
i += Asc(s, 3) * 256      <FONT Color=gray>' ''&0100''</font>
 +
i += Asc(s, 4)

Versione attuale delle 22:05, 29 ott 2021

Per varie ragioni a volte può essere necessario effettuare una lettura di taluni dati come tipo Stringa, pur non necessariamente appartenendo ad un file di testo. Ciò può risultare utile in modo particolare quando si devono leggere da un file o altro flusso due o più dati che rappresentano per noi significativi, reali valori numerici. In tal caso, quindi, la stringa, ottenuta dalla lettura del flusso di dati, contiene due più valori numerici di qualsiasi tipo (Short, Integer, etc.), che ovviamente dovranno essere riconvertiti dall'attuale rappresentazione di tipo stringa alla rappresentazione di tipo numerale per ottenenre i loro originari e reali valori.


Soluzione se i valori sono di tipo Byte

Se i valori numerali possono essere espressi dal tipo Byte, allora per trasformare ogni carattere della stringa, ottenuta dalla precedente lettura del flusso, nel corrispondente reale valore numerico di tipo Byte si potrà utilizzare molto agevolmente il metodo .FromString() appartenente alla Classe Byte[]:

Byte[].FromString(stringa) As Byte[]

che riempirà, quindi, gli elementi di una variabile vettoriale di tipo Byte[] dei valori numerici ottenuti dalla conversione di ogni carattere della stringa.

Si procederà alla lettura del valore, contenuto da ciascun elemento del vettore di tipo Byte[], nelle modalità consuete preferite.


Soluzione se i valori sono di tipo avente dimensione superiore al Byte

Nei restanti casi si potrà agire con due modalità.


1a modalità

In questa modalità si terrà conto della posizione di ciascun byte all'interno della sua rappresentazione esadecimale.
Facciamo un esempio, ipotizzando che il file sia costituito dai seguenti 10 byte:

56 34 12 00 44 33 22 11 99 00

che rappresentano in successione due Interi ed uno Short:

Public Sub Main()

 Dim s As String
 Dim i1, i2 As Integer
 Dim sh As Short
 
 s = File.Load("/percorso/del/file/da/leggere")

' Tenendo conto che il valore è rappresentato in "Little-Endian": [nota 1]
 i1 = Asc(s, 1)
 i1 += Asc(s, 2) * 256        ' &0100
 i1 += Asc(s, 3) * 65536      ' &010000
 i1 += Asc(s, 4) * 16777216   ' &01000000 

 i2 = Asc(s, 5)
 i2 += Asc(s, 6) * 256
 i2 += Asc(s, 7) * 65536
 i2 += Asc(s, 8) * 16777216

 sh = Asc(s, 9)
 sh += Asc(s, 10) * 256

 Print i1
 Print i2
 Print sh

End


Uso di una variabile di tipo Puntatore

Questa modalità prevede la crazione di una variabile di tipo Puntatore con la funzione VarPtr(), che avrà come parametro la variabile stringa contenente i dati ottenuti dalla precedente lettura del flusso.

Successivamente si provvederà a dereferenziare la variabile Puntatore mediante le specifiche funzioni fornite da Gambas (Short@(), int@(), etc.), per poter ottenere i reali valori numerici.


Facciamo un esempio, ipotizzando che il file sia costituito dai seguenti 18 byte:

44 44 44 00 33 33 33 00 22 00 11 11 11 11 11 11 11 00

che rappresentano in successione due Interi, uno Short ed un Long.

Per ricavare i numeri dei predetti tipi rappresentati da quei byte, possiamo procedere come segue:

Private s As String


Public Sub Main()

 Dim p As Pointer
 Dim i1, i2 As Integer
 Dim sh As Short
 Dim l As Long
 
' Leggiamo il file come testo e salviamo i dati nella variabile di tipo stringa "s":
 s = File.Load("/percorso/del/file/da/leggere")

' Dalla variabile stringa "s" generiamo una variabile di tipo "Puntatore" mediante la funzione "VarPtr()":
 p = VarPtr(s)

' Infine, vediamo in console i "reali" valori numerici, dereferenziando il Puntatore tenendo conto dei byte di memoria occupati da ciascun tipo di valore:
 Print Int@(p)
 Print Int@(p + 4)
 Print Short@(p + 8)
 Print Long@(p + 10)
      
End


Note

[1] Se fosse rappresentato, invece, in "Big-Endian", la conversione sarebbe:

i = Asc(s, 1) * 16777216   ' &01000000 
i += Asc(s, 2) * 65536     ' &010000
i += Asc(s, 3) * 256       ' &0100
i += Asc(s, 4)