Golang中循环变量"ch"为何不满足条件

Golang中循环变量"ch"为何不满足条件 "嗯,循环条件为真,但当我在for循环结束前更新循环变量时,条件判断没有生效"

package main

import "fmt"

func main() {
    ch := 'y'
    for ch == 'y'{

        fmt.Println("\n\na. 加法")
        fmt.Println("b. 减法")
        fmt.Println("c. 乘法")
        fmt.Println("d. 除法")

        fmt.Print("\n请输入您的选择:\t")
        fmt.Scanf("%c", &ch)

        var a, b float64

        switch ch {
        case 'a':
            {
                fmt.Print("\n输入两个数字:\t")
                fmt.Scan(&a, &b)
                fmt.Print("\n答案:\t", a+b)
            }
        case 'b':
            {
                fmt.Print("\n输入两个数字:\t")
                fmt.Scan(&a, &b)
                fmt.Print("\n答案:\t", a-b)
            }
        case 'c':
            {
                fmt.Print("\n输入两个数字:\t")
                fmt.Scan(&a, &b)
                fmt.Print("\n答案:\t", a*b)
            }
        case 'd':
            {
                fmt.Print("\n输入两个数字:\t")
                fmt.Scan(&a, &b)
                if b != 0 {
                    fmt.Print("\n答案:\t", a/b)
                } else {
                    fmt.Print("\nB必须为非零值")
                }
            }
        default:
            {
                fmt.Println("\n看起来您输入了错误的选择!!!")
            }
        }
        fmt.Print("\n\n是否要再次执行(y/n):\t\t")  
        fmt.Scan(&ch)  // 这里有什么问题
    }
}

更多关于Golang中循环变量"ch"为何不满足条件的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

这是预期的行为。来自文档

唯一的例外:动词 %c 总是扫描输入中的下一个符文,即使它是空格(或制表符等)或换行符。

因此,要么将符文替换为字符串/整数,要么逐个符文读取直到完全结束(在任何意义上)。

更多关于Golang中循环变量"ch"为何不满足条件的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题出在fmt.Scan(&ch)的输入处理上。当用户输入字符后按回车键时,换行符\n会留在输入缓冲区中,导致下一次循环读取时直接读取到这个换行符而不是新的用户输入。

以下是修复后的代码:

package main

import (
    "fmt"
    "bufio"
    "os"
)

func main() {
    ch := 'y'
    reader := bufio.NewReader(os.Stdin)
    
    for ch == 'y' {
        fmt.Println("\n\na. 加法")
        fmt.Println("b. 减法")
        fmt.Println("c. 乘法")
        fmt.Println("d. 除法")

        fmt.Print("\n请输入您的选择:\t")
        fmt.Scanf("%c", &ch)

        var a, b float64

        switch ch {
        case 'a':
            {
                fmt.Print("\n输入两个数字:\t")
                fmt.Scan(&a, &b)
                fmt.Print("\n答案:\t", a+b)
            }
        case 'b':
            {
                fmt.Print("\n输入两个数字:\t")
                fmt.Scan(&a, &b)
                fmt.Print("\n答案:\t", a-b)
            }
        case 'c':
            {
                fmt.Print("\n输入两个数字:\t")
                fmt.Scan(&a, &b)
                fmt.Print("\n答案:\t", a*b)
            }
        case 'd':
            {
                fmt.Print("\n输入两个数字:\t")
                fmt.Scan(&a, &b)
                if b != 0 {
                    fmt.Print("\n答案:\t", a/b)
                } else {
                    fmt.Print("\nB必须为非零值")
                }
            }
        default:
            {
                fmt.Println("\n看起来您输入了错误的选择!!!")
            }
        }
        
        fmt.Print("\n\n是否要再次执行(y/n):\t\t")
        // 清除输入缓冲区中的换行符
        reader.ReadString('\n')
        // 读取新的用户输入
        input, _ := reader.ReadString('\n')
        ch = rune(input[0])
    }
}

或者使用更简洁的解决方案,在fmt.Scan(&ch)前添加一个读取换行符的操作:

package main

import "fmt"

func main() {
    ch := 'y'
    
    for ch == 'y' {
        fmt.Println("\n\na. 加法")
        fmt.Println("b. 减法")
        fmt.Println("c. 乘法")
        fmt.Println("d. 除法")

        fmt.Print("\n请输入您的选择:\t")
        fmt.Scanf("%c", &ch)

        var a, b float64

        switch ch {
        case 'a':
            {
                fmt.Print("\n输入两个数字:\t")
                fmt.Scan(&a, &b)
                fmt.Print("\n答案:\t", a+b)
            }
        case 'b':
            {
                fmt.Print("\n输入两个数字:\t")
                fmt.Scan(&a, &b)
                fmt.Print("\n答案:\t", a-b)
            }
        case 'c':
            {
                fmt.Print("\n输入两个数字:\t")
                fmt.Scan(&a, &b)
                fmt.Print("\n答案:\t", a*b)
            }
        case 'd':
            {
                fmt.Print("\n输入两个数字:\t")
                fmt.Scan(&a, &b)
                if b != 0 {
                    fmt.Print("\n答案:\t", a/b)
                } else {
                    fmt.Print("\nB必须为非零值")
                }
            }
        default:
            {
                fmt.Println("\n看起来您输入了错误的选择!!!")
            }
        }
        
        fmt.Print("\n\n是否要再次执行(y/n):\t\t")
        // 清除缓冲区中的换行符
        var temp string
        fmt.Scanln(&temp)
        fmt.Scanf("%c", &ch)
    }
}

这样修改后,循环变量ch就能正确读取用户输入并正常进行条件判断了。

回到顶部