User Tools

Site Tools


pub:labprog:2020-12-17

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pub:labprog:2020-12-17 [2020/12/17 17:32] (current)
atrent created
Line 1: Line 1:
 +#  Note lezione (17/12/2020)
 +
 +testo (formattato male ma basta prendere il "grezzo", cfr. istruzioni sul wiki stesso) lezioni precedenti sul wiki del corso: http://sl-lab.it/dokuwiki/doku.php/pub:labprog:home
 +
 +## Note sulle stringhe di formato (usate ad es. in Scanf)
 +
 +Prendiamo come esempio la funzione fmt.Scanf:
 +
 +```go
 +func Scanf(format string, a ...interface{}) (n int, err error)
 +   
 +/*Scanf scans text read from standard input,
 +storing successive space-separated values into
 +successive arguments as determined by the format [...].*/
 +
 +```
 +
 +Il primo argomento di questa funzione è una "stringa di formato". La stringa di formato descrive esattamente quello che ci si aspetta di leggere come input (o scrivere in output, nel caso di una stampa).
 +
 +
 +Ad esempio, supponiamo di voler leggere una data dal linea di comando (esattamente come viene richiesto dall'esercizio 1 di oggi) nel seguente formato: `gg/mm/aaaa`.
 +
 +### Lettura corretta 
 +
 +```go
 +fmt.Sscanf(os.Args[1], "%d/%d/%d", &gg, &mm, &aa)
 +fmt.Println(gg,mm,aa)
 +```
 +
 +```bash
 +./main 15/09/2040
 +15 9 2040 # notare che lo 0 del 9 scompare
 +          # leggere sez.Lunghezza e precisione in output
 +```
 +
 +### Spazi bianchi
 +
 +Vediamo invece la seguente implementazione:
 +
 +```go 
 +fmt.Sscanf(os.Args[1], "%d / %d / %d", &gg, &mm, &aa)
 +fmt.Println(gg,mm,aa)
 +```
 +
 +La differenza rispetto a prima è che sono stati inseriti degli spazi bianchi all'interno della stringa di formato. Se alla riga di comando forniamo lo stesso input di prima, otteniamo un risultato "strambo":
 +
 +```bash 
 +./main 15/09/2040
 +15 0 0
 +```
 +
 +**Attenzione**: lo spazio bianco è un carattere, esattamente come tutti gli altri, quindi viene utilizzato come separatore. 
 +
 +Allora ci si potrebbe chiedere: mettendo gli *stessi* spazi bianchi anche dentro l'input, la lettura andrebbe a buon fine? *(leggi la prossima sezione)*
 +
 +### Le virgolette 
 +
 +```
 +./main 15 / 09 / 2040
 +15 0 0
 +```
 +
 +No, nonstante l'aggiunta degli spazi, la lettura non viene effettuata correttamente. 
 +
 +Questo perchè gli spazi sono un separatore anche per gli argomenti a linea di comando. Infatti, se aggiungiamo i seguenti comandi al nostro programma:
 +
 +```go 
 +fmt.Println("#argomenti:",len(os.Args))
 +for pos,val := range os.Args {
 +    fmt.Printf("argomento %d: %s\n", pos, val)
 +}
 +```
 +Otteniamo:
 +```
 +15 0 0
 +#argomenti: 6
 +argomento 0: ./main
 +argomento 1: 15
 +argomento 2: /
 +argomento 3: 09
 +argomento 4: /
 +argomento 5: 2040
 +```
 +
 +Quindi, per poter leggere "correttamente" la data, tutti i valori dovranno essere contenuti all'interno dell'argomento #1. Per fare ciò mettiamo tra virgolette la data intera nella linea di comando (esattamente come se fosse una stringa) :
 +
 +```
 +./main "15 / 09 / 2040"
 +15 9 2040
 +#argomenti: 2
 +argomento 0: ./main
 +argomento 1: 15 / 09 / 2040
 +```
 +
 +### Utilizzare `-` come separatore
 +
 +Supponiamo ora di avere come separatore il simbolo `-` al posto del simbolo `/`.
 +
 +L'istruzione corretta diventa quindi:
 +
 +```go 
 +fmt.Sscanf(os.Args[1], "%d-%d-%d", &gg, &mm, &aa)
 +```
 +
 +E abbiamo come effetto:
 +
 +``` 
 +./main 15-09-2040
 +15 9 2040
 +```
 +
 +**Attenzione**: se per sbaglio fosse stato omesso il simbolo `-` all'interno della stringa di formato, si sarebbero ottenuti risultati poco piacevoli:
 +
 +```go 
 +//ometto -
 +fmt.Sscanf(os.Args[1], "%d %d %d", &gg, &mm, &aa)
 +```
 +
 +``` 
 +./main 15-09-2040
 +15 0 0
 +#argomenti: 2
 +argomento 0: ./main
 +argomento 1: 15-09-2040
 +```
 +
 +Questo succede perchè il primo argomento non rispetta la stringa di formato *(infatti, il 15 viene letto, mentre tutto il resto viene scartato dal momento che ci si aspetta che ci sia lo spazio come separatore)*.
 +
 +
 +
 +### Tabellina specificatori
 +`%v` stampa una struct (senza nomi dei campi)
 +`%+v` stampa una struct con nomi dei campi 
 +`%t` bool
 +`%d` intero
 +`%c` stampa carattere (runa)
 +`%x` valore esadecimale
 +`%f` float 
 +`%s` stringa
 +
 +
 +### Lunghezza e precisione in output
 +
 +Formattazione output: `%[lunghezza_min][.precisione]<specificatore>`
 +
 +- `lunghezza`:  numero minimo di caratteri da stampare. Se il numero fornito è più corto, vengono aggiunti degli spazi bianchi **a sinstra**. Se è più lungo **non** viene tagliato.
 +
 +    Esempio: 
 +    ```go 
 +    //mi aspetto un numero da almeno 2 cifre
 +    fmt.Printf("%2d\n", 1)
 +    fmt.Printf("%2d\n", 10)
 +    fmt.Printf("%2d\n", 100)
 +
 +    fmt.Printf("%2f\n", 1.0)
 +    fmt.Printf("%2f\n", 10.0)
 +    fmt.Printf("%2f\n", 100.0)
 +
 +    ```
 +    ```bash
 +            #il primo carattere è bianco
 +    10
 +    100
 +    
 +    1.000000  #qua non accade
 +    10.000000
 +    100.000000
 +    ```
 +
 +- `precisione` : nel caso di interi è equivalente alla lunghezza, con la differenza che al posto degli spazi bianchi vengono aggiunti degli zeri a sinistra:
 +
 +    ```go 
 +    fmt.Printf("%.3d\n", 1)
 +    fmt.Printf("%2.3d\n", 1)
 +    fmt.Printf("%4.3d\n", 1)
 +    ```
 +    ```bash 
 +    001
 +    001
 +     001 # non è sbagliato, lo spazio bianco a sx
 +         # c'è perchè si devono stampare almeno 4
 +         # caratteri 
 +    ```
 +    
 +    Nel caso di float, invece, indica il numero di cifre da stampare dopo la virgola 
 +    
 +    ```go
 +    fmt.Printf("%2.0f\n", 10.42)
 +    fmt.Printf("%2.1f\n", 10.42)
 +    fmt.Printf("%2.3f\n", 10.42)
 +    ```
 +    
 +    ```
 +    10
 +    10.4
 +    10.420
 +    ```
 +
 +---
 +    
 +Tornando velocemente all'esempio della data, eravamo rimasti con: 
 +    
 +```go
 +fmt.Sscanf(os.Args[1], "%d/%d/%d", &gg, &mm, &aa)
 +fmt.Println(gg,mm,aa)
 +```
 +
 +```bash
 +./main 15/09/2040
 +15 9 2040 
 +```    
 +Se al posto di `9` volessimo stampare `09`, dovremmo modificare il codice come segue:
 +
 +```go
 +fmt.Printf("%.2d %.2d %d\n", gg, mm , aa)
 +```
 +```
 +./main 15/09/2040
 +15 09 2040
 +```
 +
 +
 +
 +
 +
 +.
 +
 +
 +
 +
  
pub/labprog/2020-12-17.txt · Last modified: 2020/12/17 17:32 by atrent