为了账号安全,请及时绑定邮箱和手机立即绑定

如何忽略 fmt.Sprintf 的额外字段

如何忽略 fmt.Sprintf 的额外字段

Go
慕仙森 2021-12-07 16:15:00
我有一个 Golang 程序,它从命令行读取字符串参数并将其传递给 fmt.Sprintf 函数。假设 tmp_str 是命令行中的目标字符串。package mainimport "fmt"func main() {    tmp_str := "hello %s"    str := fmt.Sprintf(tmp_str, "world")    fmt.Println(str)}在某些情况下,程序会传递一个完整的字符串,比如“Hello Friends”,而不是字符串模板。程序会恐慌并返回:你好朋友%!(额外的字符串=世界)那么,如何忽略 fmt.Sprintf 的额外字段呢?
查看完整描述

3 回答

?
临摹微笑

TA贡献1982条经验 获得超2个赞

是的,您可以通过切片传递给可变参数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)

}



但是您通常不使用动态格式化的字符串,这不安全,如果您想接受任何字符串,您还应该调整此代码以防止choke on %%s。如果您冒险走到这一步,那么您可能应该看看模板(它可以让您使用命名字符串,因此丢失的字符串不必是最后一个)。


查看完整回答
反对 回复 2021-12-07
?
浮云间

TA贡献1829条经验 获得超4个赞

我同意Volker 的回答,但您可以检查您的输入字符串:


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)

}


查看完整回答
反对 回复 2021-12-07
?
守着一只汪

TA贡献1872条经验 获得超3个赞

在这种特殊情况下,您可以要求命令行用户始终提供 %s 动词,并说明他们可以将字符串截断为零长度:

Hello Friends%.0s

甚至更短:

Hello Friends%.s

输出很简单:

你好朋友


查看完整回答
反对 回复 2021-12-07
  • 3 回答
  • 0 关注
  • 190 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信