2012-12-22 39 views
5

Tôi dường như đang gặp sự cố xếp hàng trong khi nhận được thông tin nhập của người dùng trong vòng lặp for in go. Đây là tôi codeLàm cách nào để sử dụng fmt.Scanf trong 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) 
    } 
} 

gì xảy ra khi tôi chạy mã này này là:

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 

Những gì tôi nhận thấy là mỗi lần lặp của vòng lặp xảy ra hai lần, điều này có thể là do Go là sử dụng song song theo mặc định và khiến cả hai bộ xử lý chạy mã trong vòng lặp for?

+2

Theo như tôi thấy, mỗi lần lặp được thực hiện chỉ một lần, 'Debug: i: n' trong đó' n' đi từ 0 đến 9 cho thấy chính xác điều đó. Hay bạn ám chỉ điều gì khác? Đây là phiên của tôi trong terminal: https://gist.github.com/4357860 Nó hoạt động chính xác như mong đợi. –

+2

Làm thế nào để đầu ra của bạn không khớp với mã của bạn? – jdi

+0

@VladimirMatveev Nếu bạn cố gắng chạy nó trên máy tính của bạn, tôi nghĩ rằng bạn sẽ thấy những gì tôi có ý nghĩa. Bạn có thấy scanf trong vòng lặp không? Nó nên đọc một giá trị từ bàn phím 10 lần. Nhưng đối với mọi đầu vào tôi đưa vào, khối lặp thực hiện hai lần. Vì vậy, tôi tăng gấp đôi. – gprasant

Trả lời

4

Bạn đang sử dụng hệ điều hành nào? Các cửa sổ?

Hãy thử điều này:

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) 
    } 
} 

Output:

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 sử dụng cửa sổ. Tôi đã thử đề xuất của bạn. Tôi vẫn gặp sự cố tương tự – gprasant

+0

Rất tiếc, tôi đã bỏ qua '\ n' trong 'fmt.Scanf ("% d \ n ", & num)'. Tôi đã thử scanfwith \ n và nó làm việc – gprasant

2

Câu trả lời ở trên là một gợi ý tốt. mã

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

sẽ xuất ra nguyên nhân của sự cố này.

10 unexpected newline 

Vì vậy, tôi thay đổi mã này và nó hoạt động.

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) 
    } 
} 

điều này là do các đầu dòng khác nhau. các cửa sổ sử dụng trở lại vận chuyển và nguồn cấp dữ liệu dòng (\r\n) làm dòng kết thúc. Unix sử dụng nguồn cấp dữ liệu dòng (\n).

bạn có thể sử dụng notepad2 để tạo tệp (a.txt) với nguồn cấp dữ liệu \r. và thực hiện việc này:

go run s.go < input.txt 

điều này sẽ hoạt động chính xác.

+0

nó là một vấn đề với absense '\ n' trong scanf. Đây có phải là một dòng cửa sổ kết thúc vấn đề? bởi vì tôi chạy cùng một mã ở trên trên mac của một người bạn và nó hoạt động hoàn hảo – gprasant

+1

điều này là do các kết thúc dòng khác nhau. các cửa sổ sử dụng trở lại vận chuyển và dòng thức ăn ('\ r \ n') như là một dòng kết thúc. Unix sử dụng nguồn cấp dữ liệu dòng ('\ n'). – pexeer

1

Chỉ cần chỉ ra fmt.Scanln (& num) có lẽ sẽ làm việc giống như fmt.Scanf ("% d \ n", & num), vì fmt.Scanln (& num) cũng kiểm tra các loại " num ".

Nói cách khác, nếu

var num float32 

fmt.Scanln(&num) 

bạn có thể nhập số nổi từ bàn điều khiển.

Các vấn đề liên quan