为什么这在GO语言中输出以下代码是错误的

时间:2016-09-17 07:20:35

标签: for-loop go stack scanf

这是我为实现Stack而编写的代码。当我执行它时,它会完全生成一些不同类型的输出。附上输出的屏幕截图。为什么程序会产生这样无效的输出?代码中有错误吗?

package main

import "fmt"

var st [100]int
var top int

func main() {
    top = -1
    ch := 0
    temp := 0
    for true {
        fmt.Println("Enter you choice:")
        fmt.Println("1. PUSH\n2. POP\n3. PRINT\n4. EXIT")
        fmt.Scanf("%d", &ch)
        switch ch {
        case 1:
            fmt.Println("Enter the value...")
            fmt.Scanf("%d", &temp)
            push(temp)
        case 2:
            temp = pop()
            if temp != -1 {
                fmt.Println("The popped value is ", temp)
            }
        case 3:
            print()
        case 4:
            break
        default:
            fmt.Println("Please enter a valid choice")
        }
    }
}

func print() {
    i := 0
    if top == -1 {
        fmt.Println("First insert elements into the stack")
    } else {
        fmt.Printf("The values are as follows")
        for i <= top {
            fmt.Println(st[i])
            i++
        }
    }
}

func pop() int {
    if top == -1 {
        fmt.Println("Please push values before popping")
        return -1
    }
    temp := st[top]
    top--
    return temp
}

func push(n int) {
    top++
    st[top] = n
}

输出的屏幕截图:

enter image description here

1 个答案:

答案 0 :(得分:1)

问题在于,您希望它像输入值一样工作,然后按 Enter 生成换行符,并尝试使用fmt.Scanf()进行扫描。引用其文档:

  

输入中的换行符必须与格式中的换行符匹配。

因此,如果您要使用fmt.Scanf(),格式字符串必须包含换行符\n。但由于你的新线没有消耗,所以读取该值的下一行将自动进行。

轻松修复:将\n添加到格式字符串:

fmt.Println("Enter you choice:")
fmt.Println("1. PUSH\n2. POP\n3. PRINT\n4. EXIT")
fmt.Scanf("%d\n", &ch)

fmt.Println("Enter the value...")
fmt.Scanf("%d\n", &temp)

另一种方法是简单地使用自动解析整行的fmt.Scanln()

fmt.Println("1. PUSH\n2. POP\n3. PRINT\n4. EXIT")
fmt.Scanln(&ch)

// ... 

fmt.Println("Enter the value...")
fmt.Scanln(&temp)

此外,fmt.Scanf()fmt.Scanln()会返回成功扫描的值的数量和错误。请务必检查扫描是否成功。

您的代码中的另一个错误是退出功能:您在break分支中使用了case 4语句。 break只会破坏switch而不会for!因此,请使用return代替break

    case 4:
        return

另一种解决方法可能是使用标签,同时请注意for true { ... }for { ... }等效(您可以省略true):

mainloop:
    for {
        // ...
        switch ch {
        // ...
        case 4:
            break mainloop
        // ...
        }
    }