Autore Topic: Estrarre da una stringa una rappresentazione numerica  (Letto 892 volte)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Estrarre da una stringa una rappresentazione numerica
« il: 24 Marzo 2018, 19:44:13 »
Quale codice suggerireste per estrapolare da una stringa la sua parte iniziale formata da caratteri numerici ?

In pratica, avendo ad esempio questa stringa (compresa fra i doppi apici e colorata):
 "123.45        testo qualsiasi"
dovete estrarre soltanto l'intera parte numerica (ossia dal carattere 1 al carattere 5 compreso il punto fra i caratteri "3" e "4", escludendo la parte che va dal primo spazio fino al carattere " i ") e convertirlo nel coerente tipo di valore (in tale caso un tipo Single o un tipo Float ).
Va da sé che quello che mi interessa vedere è soprattutto l'estrazione dei caratteri numerici.

E' ammessa qualsiasi soluzione e qualsiasi risorsa, ma - come sempre - sono preferite quelle più brevi ed eleganti.
Potete indicare più soluzioni.


« Ultima modifica: 25 Marzo 2018, 04:09:00 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline naderit

  • Grande Gambero
  • ***
  • Post: 140
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #1 il: 24 Marzo 2018, 20:26:51 »
Ciao un po' di tempo fa mi sono trovato ad estrarre dei dati da un file di testo :
     1.0         1.1       4.970  136.48  -29.83  [1]   
     1.0         1.1       4.969  136.48  -29.81  [1]   
     1.0         1.1       4.978  136.49  -29.73  [1]   
ho usato questo metodo:
Codice: [Seleziona]
 
Dim sPath As String
 Dim intfile As File
  Dim ntesto As String
  Dim vtesto As String
  Dim xtesto As String
  Dim nrighe As Integer = 0
  Dim i As Integer = 0
  Dim j As Integer = 0

  Dialog.Title = "Apri File" ' apro finestra di dialogo
  Dialog.Filter = ["*.txt", ("Text files")] ' seleziono tipo file
 
  GridView1.mode = Select.Multiple
  GridView1.Columns.Count = 5

If Dialog.OpenFile() Then Return
 
intfile = Open Dialog.Path For Input
Label2.Text = File.BaseName(Dialog.Path)

While Not Eof(intfile)

  Line Input #intfile, ntesto ' ogni riga del file è una stringa che lavoro in seguito'
 
 If nrighe > 4 Then
 
  GridView1.rows.Count = 1 + i
    GridView1[i, 0].Text = Trim$(Left$(ntesto, 17)) ' ricavo dalla stringa i dati che mi sono utili'
    GridView1[i, 1].Text = Trim$(Mid$(ntesto, 18, 8))
    GridView1[i, 2].text = CFloat(Trim$(Mid$(ntesto, 27, 8)))
    GridView1[i, 3].Text = CFloat(Trim$(Mid$(ntesto, 35, 8)))
    GridView1[i, 4].Text = CFloat(Trim$(Mid$(ntesto, 43, 8)))

  Inc i
  Endif
  Inc nrighe
 
 vtesto = Mid$(ntesto, 18, 8)
 
Wend
Close #intfile

questo è valido se i campi sono di lunghezza fissa.
ciao  :ciao:

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #2 il: 24 Marzo 2018, 20:42:30 »
Mi viene in mente qualcosa del genere:
Codice: [Seleziona]
Public Sub Main()

  Primo
  Secondo

End

Private Sub Primo()
 
  Dim s As String = "123.45        testo qualsasi"
  Dim c As String, i As Integer

  For i = 1 To Len(s)
    c = Mid(s, i, 1)
    If Asc(c) > 47 And Asc(c) < 58 Or Asc(c) = 46 Then
      Print c;
    Endif
  Next
  Print "\n"
 
End

Private Sub Secondo()
 
  Dim s As String = "123.45        testo qualsasi"
  Dim c As String, i As Integer

  For i = 1 To Len(s)
    c = Mid(s, i, 1)
    If Asc(c) = 32 Then Break
      Print c;
  Next
 
End

Ma occorrerebbe sapere se è sempre una sola stringa con un solo numero e composta come da esempuio  :-\
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #3 il: 24 Marzo 2018, 20:43:01 »
Naderit, perché hai usato l'Oggetto GridView e tutto quel codice ?



Non potresti farne un codice essenziale ?
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #4 il: 24 Marzo 2018, 20:44:40 »
Ma occorrerebbe sapere se è sempre una sola stringa con un solo numero e composta come da esempuio  :-\

 :violent:
Pure tu ti ci metti ?

Ragionate sulla stringa dell'esempio. Punto.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #5 il: 24 Marzo 2018, 21:08:19 »

Va da sé che quello che mi interessa vedere è soprattutto l'estrazione dei caratteri numerici.


Il codice da me postato estrae i caratteri numerici
 :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline naderit

  • Grande Gambero
  • ***
  • Post: 140
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #6 il: 24 Marzo 2018, 22:26:06 »
 ;D ecco,
Codice: [Seleziona]
Dim s As String = "123.45        testo qualsasi"
Dim r As Float 

r = CFloat(Trim$(Left$(s, 10))) ' i primi dieci caratteri della stringa'

Print r

quello postato in precedenza era riferito ad un file di testo che veniva visualizzato all'interno di una griglia   :ciao:
« Ultima modifica: 24 Marzo 2018, 22:28:46 da naderit »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #7 il: 24 Marzo 2018, 23:21:51 »
La più breve che mi viene in mente:
Codice: [Seleziona]
Public Sub Main()
 
  Dim s As String = "123.45        testo qualsasi"
 
  Print Scan(s, "*" & Chr(32) & "*")[0]
 
End

 :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #8 il: 25 Marzo 2018, 03:02:03 »
Bravo, Gianluigi.
Eri partito un po' svogliato, al termine della serata hai tirato fuori un'ottima soluzione.
In queste ore dicevo fra me e me: " Possibile mai che non gli venga in mente Scan() e Split() ? ".

Per Split():
Codice: [Seleziona]
Public Sub Main()
 
  Dim s As String = "123.45        testo qualsiasi"
 
  Print Split(s, Chr(32))[0]
 
End
« Ultima modifica: 25 Marzo 2018, 04:08:41 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #9 il: 25 Marzo 2018, 03:09:40 »
Codice: [Seleziona]
r = CFloat(Trim$(Left$(s, 10))) ' i primi dieci caratteri della stringa'


Come principio sarebbe accettabile; rischia, però, di non essere universale.
Ad esempio con una stringa di questo genere: "1234567890.1234        testo qualsasi"
o con quest'altra: "8        testo qualsasi" (ove i dieci caratteri vanno a comprendere anche la "t")
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #10 il: 25 Marzo 2018, 04:07:16 »
Aggiungo altre due soluzioni.

Uso della funzione esterna " sscanf( ) ".
Se la stringa prevede il simbolo locale della virgola, anziché il punto, per dividere la parte intera dalla parte frazionaria, oppure se non v'è distizione fra le predette due parti, allora potremo agevolmente...
Codice: [Seleziona]
' int sscanf (const char *__restrict __s, const char *__restrict __format, ...)
' Read formatted input from S.
Private Extern sscanf(__s As String, __format As String, dest As Pointer) As Integer In "libc:6"


Public Sub Main()

  Dim s As String = "123,45        testo qualsiasi"
  Dim f As Float

   sscanf(s, "%lf", VarPtr(f))
 
   Print f

End

Se c'è comunque il punto, allora il codice sarà un po' più complesso:
Codice: [Seleziona]
' int sscanf (const char *__restrict __s, const char *__restrict __format, ...)
' Read formatted input from S.
Private Extern sscanf(__s As String, __format As String, dest As Pointer) As Integer In "libc:6"


Public Sub Main()

  Dim s As String = "123.45        testo qualsiasi"
  Dim p As Pointer
   
   p = Alloc(SizeOf(gb.Pointer))
   
   sscanf(s, "%s", p)
 
   Print CFloat(String@(p))
 
   Free(p)

End


Volendo usare la funzione esterna "strtod( )", dovremo prevedere il simbolo locale della virgola:
Codice: [Seleziona]
' double strtod (const char *__restrict __nptr, char **__restrict __endptr)
' Convert a string to a floating-point number.
Private Extern strtod(__nptr As String, __endptr As Pointer) As Float In "libc:6"


Public Sub Main()

  Dim s As String = "123,45        testo qualsiasi"
  Dim f As Float
   
   f = strtod(s, 0)
 
   Print f

End


Possiamo usare anche la funzione esterna memccpy( ):
Codice: [Seleziona]
' void *memccpy (void *__restrict __dest, const void *__restrict __src, int __c, size_t __n)
' Copy no more than N bytes of SRC to DEST, stopping when C is found.
Private Extern memccpy(__dest As Pointer, __src As String, __c As Integer, __n As Long) In "libc:6"



Public Sub Main()

  Dim s As String = "123.45        testo qualsasi"
  Dim p As Pointer
 
   p = Alloc(SizeOf(gb.Pointer), 1)
 
   memccpy(p, s, 32, CLong(Len(s)))   ' 32 è il numero ASCII del carattere dello "spazio"'
   
   Print CFloat(Trim(String@(p)))
   
   Free(p)

End
« Ultima modifica: 26 Marzo 2018, 01:10:16 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #11 il: 25 Marzo 2018, 09:36:52 »

In queste ore dicevo fra me e me: " Possibile mai che non gli venga in mente Scan() e Split() ? ".


Veramente stavo guardando un paio di telefilm con mia moglie e poi sono scappato a nanna per via dell'ora legale.  :-[
Comunque tutte le soluzioni "rapide", in un algoritmo "vero" vanno verificate almeno con un Try e se ti restituiscono errore poi la verifica più sicura non può che essere quella carattere per carattere magari includendo anche la virgola oltre ai numeri e al punto, non trovi?

 :ciao: :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #12 il: 25 Marzo 2018, 14:54:30 »
.... verificate almeno con un Try....

Ho repulsione di Try anche ben più di Shell.



la verifica più sicura non può che essere quella carattere per carattere
Sì, ritengo sia la base essenziale.
...e infatti le funzioni esterne, da me sopra presentate, compiono anche quella verifica.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #13 il: 25 Marzo 2018, 15:15:56 »
Sì, ritengo sia la base essenziale.
...e infatti le funzioni esterne, da me sopra presentate, compiono anche quella verifica.
Beh allora non capisco il perché tu abbia snobbato i miei primi due codici...
Citazione
Ho repulsione di Try anche ben più di Shell.
:D esagerato.
Try è utile, occorre sempre tener conto dell'imprevisto tipo la classica breve momentanea mancanza di corrente, la sola trappola finale (Catch) non sempre è sufficiente.
Try a volte potrebbe essere addirittura indispensabile o comunque semplificare molto il codice (e la vita del programmatore).
Lo so meglio prevenire che curare ma la prevenzione 100% non è di noi mortali.
 :ciao: :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Estrarre da una stringa una rappresentazione numerica
« Risposta #14 il: 25 Marzo 2018, 16:34:38 »
Beh allora non capisco il perché tu abbia snobbato i miei primi due codici...
Non esagerare. Mi sono solo meravigliato che non avessi anhe proposto Scan( ) e Split( ), poiché solitamente ne fai ampio uso.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »