Ottenere i "reali" valori numerici da una lettura di tipo Stringa di un flusso di dati

Da Gambas-it.org - Wikipedia.

Per varie ragioni a volte può essere necessario effettuare una lettura di taluni 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.


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à


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":
  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 Alloc(), che avrà come parametro la variabile stringa contenente i dati ottenuti dalla precedente lettura del flusso.

Successivamente si provvederà a dereferenziare la variabile Puntatore, per poter ottenere i reali valori numerici.
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.
Facciamo un esempio, ipotizzando che il file sia costituito dai seguenti 18 byte:
56 34 12 00 44 33 22 11 99 00 98 76 54 33 22 11 01 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:

Public Sub Main()

 Dim s As String
 Dim p As Pointer
 Dim st As Stream
 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 "Alloc()":
  p = Alloc(s)

' Quindi passiamo alla dereferenziazione della variabile di tipo "Puntatore":
  st = Memory p For Read

' Leggiamo dalla variabile di tipo "Stream" (ad esempio se sappiamo che la sequenza dei valori nel flusso è come appresso):
  Read #st, i1
  Read #st, i2
  Read #st, sh
  Read #st, l

' Infine, vediamo in console i "reali" valori numerici:
  Print i1, i2, sh, l


' Va in chiusura:
  st.Close
  Free(p)
  fl.Close

End