无法在使用`reader.ReadString`捕获的字符串上检查`strings.HasSuffix`。

huangapple go评论78阅读模式
英文:

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

huangapple
  • 本文由 发表于 2016年10月30日 08:17:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/40324940.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定