英文:
Why is my go lang string comparison not working as expected?
问题
我正在尝试使用Go
,并编写了一些代码来检查输入是否为y或n:
reader := bufio.NewReader(os.Stdin)
fmt.Print("(y / n): ")
text, _ := reader.ReadString('\n')
text = strings.ToLower(text)
if strings.Compare(text, "y") == 0 {
fmt.Println("True")
} else {
fmt.Println("Else")
}
当我运行这段代码并输入y
(然后按回车键),我期望看到True
,但实际上我得到了Else
- 有人能看出问题在哪里吗?
英文:
I am dipping my toe with Go
and have written some code to check if y or n is input:
reader := bufio.NewReader(os.Stdin)
fmt.Print("(y / n): ")
text, _ := reader.ReadString('\n')
text = strings.ToLower(text)
if strings.Compare(text, "y") == 0 {
fmt.Println("True")
} else {
fmt.Println("Else")
}
When I run this code & type y
(and press enter) I expect to see True
but I get Else
- can anyone see why?
答案1
得分: 5
你可能想要的是这样的代码:
reader := bufio.NewReader(os.Stdin)
fmt.Print("(y / n): ")
text, _ := reader.ReadString('\n')
text = strings.ToLower(text[0:len(text)-1])
if strings.Compare(text, "y") == 0 {
fmt.Println("True")
} else {
fmt.Println("Else")
}
如上面的注释所说,ReadString()
函数返回的字符串包含了分隔符。所以你得到的是 "y\n"
,与 "y"
进行比较的结果是 false。(你可能更愿意使用 Trim()
函数来去除输入两侧的所有空白字符!)
编辑:Trim()
的建议应始终优先于原始建议。否则会产生非可移植的代码,正如本答案的评论中所示。完整的修订代码如下:
reader := bufio.NewReader(os.Stdin)
fmt.Print("(y / n): ")
text, _ := reader.ReadString('\n')
text = strings.ToLower(strings.Trim(text," \r\n"))
if strings.Compare(text, "y") == 0 {
fmt.Println("True")
} else {
fmt.Println("Else")
}
英文:
You most likely want something like:
reader := bufio.NewReader(os.Stdin)
fmt.Print("(y / n): ")
text, _ := reader.ReadString('\n')
text = strings.ToLower(text[0:len(text)-1])
if strings.Compare(text, "y") == 0 {
fmt.Println("True")
} else {
fmt.Println("Else")
}
As the comment above says, ReadString()
returns the delimiter as part of the string. So you're getting "y\n" and comparing to "y" - the result is false. (You might rather use the Trim()
function to remove all whitespace from either side of the input,instead!)
Edit: The Trim()
suggestion should always be preferred over the original suggestion. To do otherwise produces non-portable code, as illustrated in the comments to this answer. The complete revised code:
reader := bufio.NewReader(os.Stdin)
fmt.Print("(y / n): ")
text, _ := reader.ReadString('\n')
text = strings.ToLower(strings.Trim(text," \r\n"))
if strings.Compare(text, "y") == 0 {
fmt.Println("True")
} else {
fmt.Println("Else")
}
答案2
得分: 3
正如@TimCooper在评论中指出的那样,ReadString函数会读取输入中第一个分隔符(delim)之前的数据,并返回包含该数据和分隔符的字符串。因此,当你使用\n
作为分隔符时,它会包含在读取的文本中,所以在进行比较或去除时需要考虑这一点。
正如在其他答案的讨论中所揭示的那样,仅仅去除\n
是不够的。这可能是因为来自标准输入(stdin)的用户输入在不同操作系统上的行尾符可能不同。在UNIX中是\n
,在Windows中是\r\n
。
这里是一个更具可移植性的解决方案:
if strings.TrimRight(text, "\r\n") == "y" {
我还将使用strings.Compare
改为了直接、简单地与"y"
进行比较。
英文:
As @TimCooper pointed out in a comment,
"ReadString reads until the first occurrence of delim in the input, returning a string containing the data up to and including the delimiter".
That means, as your delimiter is \n
, it will get included in the text
read, so you need to consider that when making comparisons, or strip it out.
As revealed by the discussion on the other answer, simply stripping \n
is not enough. This is probably because the line ending of user input from stdin
may be different depending on the operating system. In UNIX it's \n
, in Windows it's \r\n
.
Here's a more portable solution:
if strings.TrimRight(text, "\r\n") == "y" {
I also changed the use of strings.Compare
to a more direct, simpler comparison with "y"
directly.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论