2012-12-22 16 views
5

Sembra che si stia verificando un problema queer durante l'input dell'utente all'interno di un ciclo for in go. Ecco il mio codeCome utilizzare fmt.Scanf in Go

package main 

import "fmt" 

func main() { 
    var num int 
    for i := 0; i < 10; i++ { 
     fmt.Printf("Debug: i : %d ", i) 
     fmt.Scanf("%d", &num) 
     fmt.Println(num) 
    } 
} 

Cosa succede quando si esegue questo codice è questo:

Debug: i : 0 
Enter next number 
1 
1 
Debug: i : 1 
Enter next number 
1 
Debug: i : 2 
Enter next number 
2 
2 
Debug: i : 3 
Enter next number 
2 
Debug: i : 4 
Enter next number 
3 
3 
Debug: i : 5 
Enter next number 
3 
Debug: i : 6 
Enter next number 
4 
4 
Debug: i : 7 
Enter next number 
4 
Debug: i : 8 
Enter next number 
5 
5 
Debug: i : 9 
Enter next number 
5 

Quello che ho notato è che ogni iterazione del ciclo avviene due volte, questo potrebbe essere perché Go è utilizzando il parallelismo per impostazione predefinita e facendo sì che entrambi i processori eseguano il codice all'interno di un ciclo for?

+2

Per quanto posso vedere, ogni iterazione viene eseguita una sola volta, 'Debug: i: n' dove' n' va da 0 a 9 suggerisce esattamente questo. O intendi qualcos'altro? Ecco la mia sessione nel terminale: https://gist.github.com/4357860 Funziona esattamente come previsto. –

+2

Come mai il tuo output non corrisponde al tuo codice? – jdi

+0

@VladimirMatveev Se provate a eseguirlo sulla vostra macchina, penso che vedrete cosa intendo. Vedi lo scanf nel loop? Dovrebbe leggere un valore dalla tastiera 10 volte. Ma per ogni input che do dentro, il blocco del ciclo viene eseguito due volte. Quindi ho incrementi due volte. – gprasant

risposta

4

Quale sistema operativo stai utilizzando? Finestre?

Prova questo:

package main 

import "fmt" 

func main() { 
    var num int 
    for i := 0; i < 10; i++ { 
     fmt.Printf("Debug: i : %d\n", i) 
     fmt.Println("Enter next number") 
     n, err := fmt.Scanf("%d\n", &num) 
     if err != nil { 
      fmt.Println(n, err) 
     } 
     fmt.Println(num) 
    } 
} 

uscita:

Debug: i : 0 
Enter next number 
1 
1 
Debug: i : 1 
Enter next number 
2 
2 
Debug: i : 2 
Enter next number 
3 
3 
Debug: i : 3 
Enter next number 
4 
4 
Debug: i : 4 
Enter next number 
5 
5 
Debug: i : 5 
Enter next number 
6 
6 
Debug: i : 6 
Enter next number 
7 
7 
Debug: i : 7 
Enter next number 
8 
8 
Debug: i : 8 
Enter next number 
9 
9 
Debug: i : 9 
Enter next number 
10 
10 
+0

Im usando windows. Ho provato il tuo suggerimento. Sto ancora avendo lo stesso problema – gprasant

+0

Mi dispiace, ho eliminato il \ N 'in 'fmt.Scanf ("% d \ n ", & num)'. Ho provato il scanfwith \ n e ha funzionato – gprasant

2

La risposta di cui sopra è un buon suggerimento. il codice

if err != nil { 
     fmt.Println(n, err) 
    } 

stamperà la ragione di questo problema.

10 unexpected newline 

Quindi cambio il codice e funziona.

package main 

import "fmt" 

func main() { 
    var num int 
    for i := 0; i < 10; i++ { 
     fmt.Printf("Debug: i : %d ", i) 
     fmt.Scanf("%d\n", &num) // add "\n" 
     fmt.Println(num) 
    } 
} 

questo a causa delle diverse terminazioni di linea. la finestra utilizza il ritorno a capo e l'avanzamento riga (\r\n) come fine riga. l'Unix usa l'avanzamento di riga (\n).

è possibile utilizzare notepad2 per creare un file (a.txt) con il feed di riga \r. e fare questo:

go run s.go < input.txt 

questo funzionerà correttamente.

+0

è stato un problema con l'assenza '\ n' nella scanf. Si tratta di un problema di fine riga di Windows? perché ho eseguito lo stesso codice sopra nel Mac di un amico e ha funzionato perfettamente – gprasant

+1

a causa delle diverse terminazioni di linea. la finestra utilizza il ritorno a capo e il feed di riga ('\ r \ n') come una fine di riga. l'Unix usa il feed di riga ('\ n'). – pexeer

1

Giusto per sottolineare fmt.Scanln (& num) sarebbe probabilmente funzionerà lo stesso di fmt.Scanf ("% d \ n", & num), dal momento che fmt.Scanln (& num) controllare anche il tipo di " num".

In altre parole, se

var num float32 

fmt.Scanln(&num) 

è possibile inserire il numero di galleggiamento dalla console.