drsh30452
2016-01-27 16:45
浏览 131
已采纳

如何忽略fmt.Sprintf的其他字段

I have a Golang program that reads a string parameter from command line and passes it to the fmt.Sprintf function. Let's say tmp_str is the target string from command line.

package main

import "fmt"

func main() {
    tmp_str := "hello %s"
    str := fmt.Sprintf(tmp_str, "world")
    fmt.Println(str)
}

In some cases, the program will pass a completed string like "Hello Friends", instead of a string template.. The program would panic and return:

Hello Friends%!(EXTRA string=world)

So, how to ignore the extra fields for fmt.Sprintf?

图片转代码服务由CSDN问答提供 功能建议

我有一个Golang程序,该程序从命令行读取字符串参数并将其传递给fmt.Sprintf函数。 假设tmp_str是命令行中的目标字符串。

 包main 
 
import“ fmt” 
 
func main(){
 tmp_str:=“ hello%  s“ 
 str:= fmt.Sprintf(tmp_str,” world“)
 fmt.Println(str)
} 
   
 
 

程序将传递完整的字符串,例如“ Hello Friends”,而不是字符串模板。。程序将惊慌并返回:

Hello Friends%!(EXTRA string = 世界)

那么,如何忽略fmt.Sprintf的额外字段?

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

5条回答 默认 最新

  • dongpaipu8394 2016-01-27 17:46
    已采纳

    Yes you can do it, by slicing the arguments you pass to the variadic Sprintf function:

    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 1

    Demonstration 2 (a different version outputting even when there's more %s than arguments)

    But you don't usually use dynamic formatted strings, this isn't secure and if you want to accept any string, you should also adapt this code to no choke on %%s. If you venture this far, then you should probably have a look at templates (which would let you use named strings, and thus the missing one wouldn't have to be the last one).

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • dongpin1850 2016-01-27 16:48

    You cannot do this.

    You have to find a different solution.

    评论
    解决 无用
    打赏 举报
  • dongyuan8469 2016-01-27 17:22

    I agree with Volker's answer, but you could check your input string:

    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)
    }
    
    评论
    解决 无用
    打赏 举报
  • dongque20030402 2016-12-18 14:04

    In this particular case, you could require the command line users to always supply a %s verb, and explain they can truncate the string to zero length:

    Hello Friends%.0s
    

    or even shorter:

    Hello Friends%.s
    

    The output is plain:

    Hello Friends

    评论
    解决 无用
    打赏 举报
  • du958642589 2019-07-17 06:00

    I use this one (which can probably be expanded on)

    Sprintf("Hello"+"%[2]s", "World", "")
    Sprintf("Hello %s"+"%[2]s", "World", "")
    
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题