英文:
Can't check strings.HasSuffix on string captured with reader.ReadString
问题
概述:我之前使用fmt.Scanln
来捕获字符串,但我需要字符串中包含空格,所以我开始使用reader.ReadString
。我需要检查字符串中是否存在后缀,以进行一些替换操作,所以我使用了strings.HasSuffix
。在使用fmt.Scanln
捕获的字符串中没有问题,但现在使用reader.ReadString
后,无法在字符串中找到给定的后缀。
有关发生了什么的线索吗?
以下是一个隔离问题的测试代码,请在桌面安装的Go环境中使用,而不是在线环境。
package main
import (
"bufio"
"fmt"
"strings"
"os"
"reflect"
)
const TOKEN string = ":="
func validate(expr string) {
fmt.Println("var type: ", reflect.TypeOf(expr))
if strings.Contains(expr, TOKEN) {
fmt.Println(expr, "contains works")
} else {
fmt.Println("error with contains")
}
if strings.HasSuffix(expr, TOKEN) {
fmt.Println(expr, "suffix works")
} else {
fmt.Println("error with suffix")
}
}
func main() {
var expr2 string
reader := bufio.NewReader(os.Stdin)
fmt.Print("type something finished with ':='")
expr1, _ := reader.ReadString('\n')
fmt.Scanln(&expr2)
fmt.Println("validation with reader:")
validate(expr1)
fmt.Println()
fmt.Println("validation with Scanln:")
validate(expr2)
}
英文:
Overview: I was capturing strings with fmt.Scanln, but one of my needs is that the string must have spaces so I started to use reader.ReadString, I have to check the presence of a suffix in that string to make some replacing, so I used strings.HasSuffix. With strings captured with fmt.Scanln there was no problema but now that I use reader.ReadString it is unabled to find the given suffix in the string.
Is there a clue on what's going on?
Here is a test that isolate the problem, use it in desktop installed Go, not online.
package main
import (
"bufio"
"fmt"
"strings"
"os"
"reflect"
)
const TOKEN string = ":="
func validate(expr string) {
fmt.Println("var type: ", reflect.TypeOf(expr))
if strings.Contains(expr, TOKEN) {
fmt.Println(expr, "contains works")
} else {
fmt.Println("error with contains")
}
if strings.HasSuffix(expr, TOKEN) {
fmt.Println(expr, "suffix works")
} else {
fmt.Println("error with suffix")
}
}
func main() {
var expr2 string
reader := bufio.NewReader(os.Stdin)
fmt.Print("type something finished with ':='")
expr1, _ := reader.ReadString('\n')
fmt.Scanln(&expr2)
fmt.Println("validation with reader: ")
validate(expr1)
fmt.Println()
fmt.Println("validation with Scanln: ")
validate(expr2)
}
答案1
得分: 3
根据@Tim的提到,reader.ReadString('\n')
的输出包括最后一个字符\n
,而fmt.Scanln
则不包括。你可以选择使用const TOKEN string = ":=\n"
或者从字符串末尾删除\n
。
更新:
有些情况下,\r\n
会作为后缀出现,而不是通常期望的\n
(Windows机器?)
根据fmt
的godoc,fmt.Scanln
也处理了这种情况。
在所有的扫描函数中,紧跟在回车符后面的换行符被视为普通的换行符(\r\n与\n的含义相同)。
英文:
As @Tim mentioned the output of reader.ReadString('\n')
includes '\n' as the last character and fmt.Scanln
does not do that. You can either do const TOKEN string = ":=\n"
or remove the '\n' from the end of the string.
Update :
There are cases where \r\n
occurs as a suffix instead of the usually expected\n
(Windows Machines ?)
fmt.Scanln
handles that case as well, as per fmt
godoc.
In all the scanning functions, a carriage return followed immediately by a newline is treated as a plain newline (\r\n means the same as \n).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论