Differenze tra le versioni di "Scanf()"

Da Gambas-it.org - Wikipedia.
 
(17 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
La funzione della libreria di C
 
La funzione della libreria di C
  ''int scanf(char *format, args ...)''
+
  ''int scanf (const char *__restrict __format, ...)''
legge l'input da ''stdin''. Essa consente di inserire dati nello standard inpt.
+
legge l'input da ''stdin''. Essa consente di inserire dati nello standard input. Il dato inserito e contenuto nel scondo parametro, o in ciascun parametro (se previsti più di uno) diverso dal primo, viene restituito formattato in base alla stringa di formattazione ''format''. Per ottenere dunque più dati, distinti fra loro, formattati, bisognerà prevedere un numero di argomenti (diversi dal primo) pari al numeri dei dati predetti.
 +
<BR>Va precisato che la stringa di formattazione è costituita dal carattere % e da altro carattere in base al tipo di valore immesso nell'input, ed in particolare:
 +
"%c" per ottenere un carattere;
 +
"%d" per ottenere un intero;
 +
"%f" per ottenere un Float;
 +
"%s" per ottenere una stringa (priva di spazi !);
 +
"%p" per ottenere un indirizzo di memoria.
 +
La Direttiva di conversione "s" con ''scanf( )'' accetta una stringa di caratteri non comprendente gli spazi: quando viene incontrato uno spazio, la lettura dell'input si arresta. <SUP>&#91;[[#Note|nota 1]]&#93;</sup>
  
  
Se il programmatore vuole utilizzare la funzione ''scanf()'' per immettere ''una'' parola, dovrà utilizzarla all'interno di una libreria esterna specifica da lui creata, come segue.
+
Volendola utilizzare in Gambas, bisognerà dichiararla con ''Extern'', nonché dichiarare la libreria di C: ''libc.so.6'', nella quale la funzione è contenuta:
 +
Private <FONT color=#B22222>Extern scanf</font>(__format As String, argom As Pointer<FONT Color=gray>, [qui altri eventuali parametri As Pointer]</font>) As Integer In "<FONT color=#B22222>libc:6</font>"
  
La libreria esterna specifica, il cui file di codice sorgente sarà chiamato ad esempio ''libimm.c'', può essere:
+
 
  #include <stdio.h>
+
===Esempio con immissione di una Stringa===
 +
In questo esempio si potrà immettere dallo ''standard Input'' una stringa, formata da uno o più caratteri, purché priva di spazi. Qualora vengano immessi caratteri separati da caratteri spazio, tutti i caratteri posti alla destra del primo carattere spazio non saranno scritti in console.
 +
<FONT Color=gray>' ''int scanf (const char *__restrict __format, ...)''
 +
' ''Read formatted input from stdin.''</font>
 +
  Private Extern <FONT color=#B22222>scanf</font>(__format As String, argom As Pointer) As Integer In "<FONT color=#B22222>libc:6</font>"
 +
 
 +
 +
Public Sub Main()
 
   
 
   
 +
  Dim p As Pointer
 
   
 
   
char s;
+
  p = Alloc(SizeOf(gb.Byte), 16)
 
   
 
   
  char * immetti() {
+
  <FONT color=#B22222>scanf</font>("%s", p)
 +
 
 +
  <FONT Color=gray>' ''Viene restituita una stringa:''</font>
 +
  Print String@(p)
 
   
 
   
   scanf("%s", &s);
+
   Free(p)
 
   
 
   
    return (&s);
+
End
}
+
 
e verrà posta ad esempio nella cartella "''Dati''" dell'applicativo.
+
 
  
Il codice Gambas potrà essere:
+
In questo altro esempio si potranno immettere dallo ''standard Input'' due (o più) dati separati da uno spazio. <SUP>&#91;[[#Note|Nota 1]]&#93;</sup>
  '''Private''' Extern immetti() As String In "/tmp/libimm"
+
  <FONT Color=gray>' ''int scanf (const char *__restrict __format, ...)''
+
' ''Read formatted input from stdin.''</font>
 +
Private Extern <FONT color=#B22222>scanf</font>(__format As String, argom1 As Pointer, argom2 As Pointer) As Integer In "<FONT color=#B22222>libc:6</font>"
 +
 
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
   Dim s As String
+
   Dim p1, p2 As Pointer
 
   
 
   
 +
  p1 = Alloc(SizeOf(gb.Byte), 16)
 
   
 
   
  Shell "gcc -o /tmp/libimm.so " & Application.Path &/ "libimm.c -shared -fPIC" Wait
+
  p2 = Alloc(SizeOf(gb.Byte), 16)
 
   
 
   
   s = immetti()
+
  <FONT color=#B22222>scanf</font>("%s %s", p1, p2)
 +
    
 +
  Print String@(p1), String@(p2)
 
   
 
   
  Print s
+
  Free(p1)
 +
  Free(p2)
 
   
 
   
  '''End'''
+
  End
La parola da immettere potrà essere inserita dalla console dell'IDE di Gambas, oppure - se creato l'eseguibile ''.gambas'' - dal Terminale ove sarà stato lanciato. In caso di uso dell'applicativo da Terminale, dopo aver creato l'eseguibile ''.gambas'', la libreria esterna da noi creata va posta al di fuori dell'applicativo e, nell'esempio fatto, nel medesimo percorso dell'applicativo.
 
  
  
===Raccogliere il valore stringa da un parametro della funzione chiamante di Gambas===
 
Se si intende raccogliere il valore stringa da un parametro della funzione chiamante di Gambas, i codici saranno i seguenti.
 
  
Il codice della libreria da noi creata:
+
===Esempio con Intero===
  char s;
+
In questo esempio inseriamo un valore numerico intero:
 +
  <FONT Color=gray>' ''int scanf (const char *__restrict __format, ...)''
 +
' ''Read formatted input from stdin.''</font>
 +
Private Extern <FONT color=#B22222>scanf</font>(__format As String, argom As Pointer) As Integer In "<FONT color=#B22222>libc:6</font>"
 +
 
 +
 +
Public Sub Main()
 
   
 
   
void immetti(char * t[]) {
+
  Dim p As Pointer
 
   
 
   
  scanf("%s", &s);
+
  p = Alloc(SizeOf(gb.Integer), 1)
 
    
 
    
  *t = &s;
+
  <FONT color=#B22222>scanf</font>("%d", p)
 +
   
 +
  Print Int@(p)
 +
 +
  Free(p)
 +
 +
End
 +
 
 +
 
 +
===Esempio con un Carattere (tipo ''Byte'')===
 +
In questo esempio inseriamo un Carattere (tipo ''Byte''). Verrà restituito in console il valore ASCII del carattere immesso:
 +
<FONT Color=gray>' ''int scanf (const char *__restrict __format, ...)''
 +
' ''Read formatted input from stdin.''</font>
 +
Private Extern <FONT color=#B22222>scanf</font>(__format As String, argom As Pointer) As Integer In "<FONT color=#B22222>libc:6</font>"
 
    
 
    
  }
+
   
 +
Public Sub Main()
 +
 +
  Dim p As Pointer
 +
 +
  p = Alloc(SizeOf(gb.Byte), 1)
 +
 
 +
  <FONT color=#B22222>scanf</font>("%d", p)
 +
 +
  Print Byte@(p)
 +
 +
  Free(p)
 +
 
 +
End
  
  
Il codice Gambas:
+
===Esempio con un valore di tipo ''Float''===
  '''Private''' Extern immetti(po As Pointer) In "/tmp/libimm"
+
In questo esempio inseriamo un valore numerico in virgola mobile di tipo ''Float''. Bisognerà avere l'accortezza di rispettare il simbolo ''locale'' (per noi la virgola) quale segno di distinzione fra la parte intera e quella decimale del numero in virgola mobile.
 +
  <FONT Color=gray>' ''int scanf (const char *__restrict __format, ...)''
 +
' ''Read formatted input from stdin.''</font>
 +
Private Extern <FONT color=#B22222>scanf</font>(__format As String, argom As Pointer) As Integer In "<FONT color=#B22222>libc:6</font>"
 +
 
 
   
 
   
   
+
  Public Sub Main()
'''Public''' Sub Main()
 
 
   
 
   
 
   Dim p As Pointer
 
   Dim p As Pointer
 +
 
 +
  p = Alloc(SizeOf(gb.Float), 1)
 +
 
 +
  <FONT color=#B22222>scanf</font>("%lf", p)
 +
 
 +
  Print Float@(p)
 +
 
 +
  Free(p)
 +
 
 +
End
 +
 +
 +
===Uso di un vettore di tipo ''Byte[ ]'' al posto di una variabile di tipo ''Puntatore''===
 +
Ovviamente al posto di una variabile di tipo ''Puntatore'' si potrà fare uso di un vettore di tipo ''Byte[ ]'':
 +
Library "libc:6"
 
   
 
   
 +
<FONT Color=gray>' ''int scanf (const char *__restrict __format, ...)''
 +
' ''Read formatted input from stdin.''</font>
 +
Private Extern <FONT color=#B22222>scanf</font>(__format As String, argom As Byte[]) As Integer In "<FONT color=#B22222>libc:6</font>"
 
   
 
   
  Shell "gcc -o /tmp/libimm.so " & Application.Path &/ "libimm.c -shared -fPIC" Wait
 
 
   
 
   
   immetti(VarPtr(p))
+
Public Sub Main()
 +
 
 +
  Dim dest As New Byte[]
 +
    
 +
  <FONT color=#B22222>scanf</font>("%s", dest)
 +
 
 +
<FONT Color=gray>' ''Non avendo creato con la parola "New" l'Oggetto vettore, si dovrà usare solo la proprietà ".Data" del vettore, da dereferenziare con la funzione "String@()", per leggere i dati ivi contenuti:''</font>
 +
  Print String@(dest.Data)
 
   
 
   
  Print String@(p)
+
End
+
 
'''End'''
+
 
 +
 
 +
=Note=
 +
[1] Per evitare tale "limite", imposto dal carattere dello "spazio" con la funzione "scanf()", è opportuno utilizzare la funzione esterna [[Fgets_()|fgets( )]].

Versione attuale delle 07:20, 7 giu 2024

La funzione della libreria di C

int scanf (const char *__restrict __format, ...)

legge l'input da stdin. Essa consente di inserire dati nello standard input. Il dato inserito e contenuto nel scondo parametro, o in ciascun parametro (se previsti più di uno) diverso dal primo, viene restituito formattato in base alla stringa di formattazione format. Per ottenere dunque più dati, distinti fra loro, formattati, bisognerà prevedere un numero di argomenti (diversi dal primo) pari al numeri dei dati predetti.
Va precisato che la stringa di formattazione è costituita dal carattere % e da altro carattere in base al tipo di valore immesso nell'input, ed in particolare:

"%c" per ottenere un carattere;
"%d" per ottenere un intero;
"%f" per ottenere un Float;
"%s" per ottenere una stringa (priva di spazi !);
"%p" per ottenere un indirizzo di memoria.

La Direttiva di conversione "s" con scanf( ) accetta una stringa di caratteri non comprendente gli spazi: quando viene incontrato uno spazio, la lettura dell'input si arresta. [nota 1]


Volendola utilizzare in Gambas, bisognerà dichiararla con Extern, nonché dichiarare la libreria di C: libc.so.6, nella quale la funzione è contenuta:

Private Extern scanf(__format As String, argom As Pointer, [qui altri eventuali parametri As Pointer]) As Integer In "libc:6"


Esempio con immissione di una Stringa

In questo esempio si potrà immettere dallo standard Input una stringa, formata da uno o più caratteri, purché priva di spazi. Qualora vengano immessi caratteri separati da caratteri spazio, tutti i caratteri posti alla destra del primo carattere spazio non saranno scritti in console.

' int scanf (const char *__restrict __format, ...)
' Read formatted input from stdin.
Private Extern scanf(__format As String, argom As Pointer) As Integer In "libc:6"
 

Public Sub Main()

 Dim p As Pointer

 p = Alloc(SizeOf(gb.Byte), 16)

 scanf("%s", p)
  
' Viene restituita una stringa:
 Print String@(p)

 Free(p)

End


In questo altro esempio si potranno immettere dallo standard Input due (o più) dati separati da uno spazio. [Nota 1]

' int scanf (const char *__restrict __format, ...)
' Read formatted input from stdin.
Private Extern scanf(__format As String, argom1 As Pointer, argom2 As Pointer) As Integer In "libc:6"
 

Public Sub Main()

 Dim p1, p2 As Pointer

 p1 = Alloc(SizeOf(gb.Byte), 16)

 p2 = Alloc(SizeOf(gb.Byte), 16)

 scanf("%s %s", p1, p2)
  
 Print String@(p1), String@(p2)

 Free(p1)
 Free(p2)

End


Esempio con Intero

In questo esempio inseriamo un valore numerico intero:

' int scanf (const char *__restrict __format, ...)
' Read formatted input from stdin.
Private Extern scanf(__format As String, argom As Pointer) As Integer In "libc:6"
 

Public Sub Main()

 Dim p As Pointer

 p = Alloc(SizeOf(gb.Integer), 1)
 
 scanf("%d", p)
   
 Print Int@(p)

 Free(p)

End


Esempio con un Carattere (tipo Byte)

In questo esempio inseriamo un Carattere (tipo Byte). Verrà restituito in console il valore ASCII del carattere immesso:

' int scanf (const char *__restrict __format, ...)
' Read formatted input from stdin.
Private Extern scanf(__format As String, argom As Pointer) As Integer In "libc:6"
 

Public Sub Main()

 Dim p As Pointer

 p = Alloc(SizeOf(gb.Byte), 1)
 
 scanf("%d", p)

 Print Byte@(p)

 Free(p)
  
End


Esempio con un valore di tipo Float

In questo esempio inseriamo un valore numerico in virgola mobile di tipo Float. Bisognerà avere l'accortezza di rispettare il simbolo locale (per noi la virgola) quale segno di distinzione fra la parte intera e quella decimale del numero in virgola mobile.

' int scanf (const char *__restrict __format, ...)
' Read formatted input from stdin.
Private Extern scanf(__format As String, argom As Pointer) As Integer In "libc:6"
 

Public Sub Main()

 Dim p As Pointer
  
 p = Alloc(SizeOf(gb.Float), 1)
  
 scanf("%lf", p)
  
 Print Float@(p)
  
 Free(p)
  
End


Uso di un vettore di tipo Byte[ ] al posto di una variabile di tipo Puntatore

Ovviamente al posto di una variabile di tipo Puntatore si potrà fare uso di un vettore di tipo Byte[ ]:

Library "libc:6"

' int scanf (const char *__restrict __format, ...)
' Read formatted input from stdin.
Private Extern scanf(__format As String, argom As Byte[]) As Integer In "libc:6"


Public Sub Main()
 
 Dim dest As New Byte[]
  
 scanf("%s", dest)
  
' Non avendo creato con la parola "New" l'Oggetto vettore, si dovrà usare solo la proprietà ".Data" del vettore, da dereferenziare con la funzione "String@()", per leggere i dati ivi contenuti:
 Print String@(dest.Data)

End


Note

[1] Per evitare tale "limite", imposto dal carattere dello "spazio" con la funzione "scanf()", è opportuno utilizzare la funzione esterna fgets( ).