【问题标题】:Parsing integer from exec.Command output从 exec.Command 输出解析整数
【发布时间】:2016-06-10 21:57:45
【问题描述】:

我目前正在尝试从我的 Go 程序中运行一个命令并从响应中解析一个整数。该命令返回如下输出:

6
fyb_src/ex1.fyb (1) 获胜!

使用strings.Splitstrings.TrimSpaces 分割行并删除空格可以正常工作。但是,在尝试将数字解析为整数时,出现以下错误:

恐慌:strconv.ParseInt:解析“0 \r1 \r2 \r3 \r4 \r5 \r6”:语法无效

但是将我尝试解析的字符串打印到终端会产生以下结果:

6

我不确定从这里去哪里。这个数字对我来说显然是一个整数。错误消息也没有用(至少对我来说)。有人有想法吗?

编辑:我正在运行的代码

    out, _ := exec.Command(pwd+"/osx_fukyobrane_amd64", "fyb_src/"+filename, "fyb_src/salty.fyb", "t").CombinedOutput()
    parts := strings.Split(string(out), "\n")

    fmt.Println(parts[0])

    rounds, err := strconv.Atoi(strings.TrimSpace(parts[0]))
    if err != nil {
        panic(err.Error())
    }

【问题讨论】:

  • 添加您调用ParseInt 的部分可能会有所帮助。
  • @cnicutar 感谢您的评论,我已经添加了相关代码。

标签: go


【解决方案1】:

您的问题似乎是parts[0] 包含字符串"0 \r1 \r2 \r3 \r4 \r5 \r6" 而不是数字。

strconv.Atoi 函数只寻找一个要解析的数字——我假设在这种情况下您正试图获得第一个“0”。如果是这样,问题是这段代码:strings.Split(string(out), "\n") 只是在寻找“\n”而不是“\r”,这显然是从 osx_fukyobrane_amd64 返回的内容。

一种解决方案是像这样拆分行:

regexp.MustCompile(`[\r\n]+`).Split(parts[0], -1)

这会将多行合并为一行,并将 \r、\n 和 \r\n(或其他奇怪的组合)视为有效的换行符。

【讨论】:

  • 实际上最后一个\r6 包含所需的数字(6)。使用正则表达式拆分 string(out) 会在索引 len(parts)-3 处为 strconv.Atoi 生成正确的字符串。我不认为我真的理解这里发生了什么(我得到了正则表达式,但不是为什么终端中的字符串“6”在内部会是一些疯狂的字符串)。无论如何,非常感谢您的帮助。
  • 您尝试捕获的输出格式是什么?你说它是“6”,但为什么呢?总是第6行吗?还是最后一个?还是什么?
  • 我的问题中第一个块引用的内容就是您在终端中看到的内容。它似乎是6 \n fyb_src/ex1.fyb (1) wins!,但正如我们所见,它不是。错误消息始终为0 \r1 \r2 ...\rn,其中n 是实际数字(在本例中为6)。所以在这种情况下是0 \r1 \r2 \r3 \r4 \r5 \r6
  • Hm - 我会尝试从命令行手动运行命令并将其发送到文件(例如osx_fukyobrane_amd64 fyb_src/whatever fyb_src/salty.fyb t > temp.out),然后在其上运行 hexdump 以查看它输出的确切字节,例如hexdump -C temp.out
【解决方案2】:

使用strings.Fields 代替Split,它会自动处理\n\r

这也比使用正则表达式快得多,后者在 Go 中相当慢,尽管它正在得到改进。

func splitAndTrim(line string) []string {
    out := strings.Fields(line)
    for i, s := range out {
        out[i] = strings.TrimSpace(s)
    }
    return out
}

playground

【讨论】:

    【解决方案3】:

    看起来该行可能有一些额外的转义数据。尝试按空间分割并使用它。

    out, _ := exec.Command(pwd+"/osx_fukyobrane_amd64", "fyb_src/"+filename, "fyb_src/salty.fyb", "t").CombinedOutput()
    parts := strings.Split(string(out), "\n")
    
    parts = strings.Split(parts, " ")
    
    fmt.Println(parts[0])
    
    rounds, err := strconv.Atoi(strings.TrimSpace(parts[0]))
    if err != nil {
        panic(err.Error())
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      • 2013-12-04
      • 2015-04-26
      • 1970-01-01
      相关资源
      最近更新 更多