我有一个Golang程序,它从命令行读取字符串参数并将其传递给fmt.Sprintf函数。让我们说tmp_str是来自命令行的目标字符串。
AFTER
在某些情况下,程序会传递一个完整的字符串,例如" Hello Friends",而不是字符串模板..程序会惊慌失措并返回:
Hello Friends%!(EXTRA string = world)
那么,如何忽略fmt.Sprintf的额外字段?
答案 0 :(得分:7)
是的,你可以通过将传递的参数切换到可变参数Sprintf
函数来实现:
func TruncatingSprintf(str string, args ...interface{}) (string, error) {
n := strings.Count(str, "%s")
if n > len(args) {
return "", errors.New("Unexpected string:" + str)
}
return fmt.Sprintf(str, args[:n]...), nil
}
func main() {
tmp_str := "hello %s %s %s" // don't hesitate to add many %s here
str, err := TruncatingSprintf(tmp_str, "world") // or many arguments here
if err != nil {
fmt.Println(err)
return
}
fmt.Println(str)
}
Demonstration 2(即使%s多于参数,也会输出不同的版本)
但是你通常不使用动态格式化字符串,这不安全,如果你想接受任何字符串,你也应该调整这段代码,使%%s
上没有阻塞。 。如果你冒险这么远,那么你应该看看templates(这会让你使用命名字符串,因此丢失的字符串不一定是最后一个)。
答案 1 :(得分:4)
我同意Volker's answer,但您可以检查输入字符串:
package main
import (
"fmt"
"strings"
)
func main() {
tmp_str := "hello %s"
res := tmp_str
if strings.Count(tmp_str, "%s") == 1 {
res = fmt.Sprintf(tmp_str, "world")
}
fmt.Println(res)
}
答案 2 :(得分:2)
在这种特殊情况下,您可以要求命令行用户始终提供%s动词,并解释他们可以将字符串截断为零长度:
Hello Friends%.0s
甚至更短:
Hello Friends%.s
输出很简单:
你好朋友
答案 3 :(得分:0)
我使用这个(可能可以扩展)
Sprintf("Hello"+"%[2]s", "World", "")
Sprintf("Hello %s"+"%[2]s", "World", "")
答案 4 :(得分:-4)
你不能这样做。
您必须找到不同的解决方案。